﻿//#include "AbstractWrapper.h";
#include <iostream>
#include <string>
#include <cctype>
#include <map>
#include <vector>
#include <ctype.h>
#include <stack>
#include <algorithm>
#include <sstream>
#include "QueryProcessor.h"
#include "validation.h";
#include <set>
using namespace std;
string errors[10];





// Query Preprocessor functions for query parser.
inline string QueryProcessor::trim(string& str)
{
	str.erase(0, str.find_first_not_of(' '));      
	str.erase(str.find_last_not_of(' ')+1);         
	return str;
}

void QueryProcessor::toLowerCase(string &str)
{
	const int length = str.length();
	for(int i=0; i < length; ++i)
	{
		str[i] = std::tolower(str[i]);
	}
}

string QueryProcessor::filterQuote(string dashStr){
	if((dashStr.length()>1)&&(dashStr.substr(0,1)=="\"")){
		dashStr=dashStr.substr(1);
		dashStr=dashStr.substr(0,dashStr.length()-1);
	}
	return dashStr;
}

int QueryProcessor::is_digit (int c)
{
	if (c >= '0' && c <='9')
		return 1;
	else
		return 0;
}

string QueryProcessor::filterDash(string dashStr){
	if((dashStr.length()>1)&&(dashStr.substr(0,1)=="_")){
		dashStr=dashStr.substr(1);
		dashStr=dashStr.substr(0,dashStr.length()-1);
		dashStr=filterQuote(dashStr);
	}
	return dashStr;
}

void QueryProcessor::explode(string str, string separator, vector<string>* results){
	int found;
	found = str.find_first_of(separator);
	while(found != string::npos){
		if(found > 0){
			results->push_back(str.substr(0,found));
		}
		str = str.substr(found+1);

		found = str.find_first_of(separator);
	}

	if(str.length()> 0){		
		results->push_back(str);
	}
}

string QueryProcessor::capitalize(string str)
{
	string::iterator it(str.begin());

	if (it != str.end())
		str[0] = toupper((unsigned char)str[0]);

	while(++it != str.end())
	{
		*it = tolower((unsigned char)*it);
	}
	return str;
}

string& QueryProcessor::replace(string& str,const string& old_value,const string& new_value)   
{   
	for(string::size_type pos(0); pos!=string::npos; pos+=new_value.length()){   
		if((pos=str.find(old_value,pos))!=string::npos   )   
			str.replace(pos,old_value.length(),new_value);   
		else break;   
	}   
	return str;   
} 

int QueryProcessor::priority(char a) {
	int temp=0;
	if (a == '^'){
		temp = 1;
	}else if (a == '*' || a == '/'){
		temp = 2;
	}else if (a == '+' || a == '-'){
		temp = 3;
	}else if (a=='('){
		temp=4;
	}
	return temp;
}



size_t QueryProcessor::findOp(string str){
	size_t plus_p=str.find("+");
	size_t minus_p=str.find("-");
	size_t times_p=str.find("*");

	size_t temp=1000;

	if(plus_p>=0&&plus_p<100){
		if(plus_p<temp)
			temp=plus_p;
	}
	if(minus_p>=0&&minus_p<100){
		if(minus_p<temp)
			temp=minus_p;
	}
	if(times_p>=0&&times_p<100){
		if(times_p<temp)
			temp=times_p;
	}

	return temp;
}

string QueryProcessor::convertInt(int number)
{
	stringstream ss;
	ss << number;
	return ss.str();
}

vector<string> splitS(string s, char sep) {
	vector<string> strvec;
	string strtemp;
	string::size_type pos1, pos2;
	pos2 = s.find(sep);
	pos1 = 0;        
	while (string::npos != pos2)
	{
		strvec.push_back(s.substr(pos1, pos2 - pos1));
		pos1 = pos2 + 1;
		pos2 = s.find(sep, pos1);
	}
	strvec.push_back(s.substr(pos1));
	return strvec;
}

string trimL(string aimString) {
	string output;
	int p = aimString.find_first_not_of(" \r\t");
	output = aimString.substr(p);
	return output;
}

string QueryProcessor::convertName(string name, map<string,string> args)
{

	vector<string> temp;
	//toLowerCase(name);
	explode(name, ".", &temp);


	if(temp.size()>1){
		string ck=trim(temp.at(1));
		string nm=trim(temp.at(0));
		toLowerCase(ck);
		
		if(ck=="procname"){
			if(args[nm]=="Call"){
				return "CallProc";
			}else{
				return nm;
			}
		}
			
		if(ck=="varname"||ck=="value"||ck=="stmt#"){
			return nm;
		}

		return name;
	}
   return name;
}

string QueryProcessor::splitString(string input,int pos){
	vector<string> temp;
	size_t p=input.find(".");
	if(p>0&&p<20){
		explode(input,".",&temp);
		return temp.at(pos);
	}else{
		return input;
	}
}



bool QueryProcessor::queryParser(){
	string temp, tempName,tempType, query, body_query, select_query, func_query, pattern_query, paramType;
	size_t p,p1,select_p,function_p=0,pattern_p=0, with_p=0;
	map<string,string> args;
	set<string> sync;
	set<string> stFunc;
	set<string> otFunc;
	set<string> argList;
	QueryProcessor qp;
	Validation validate;


	query=trim(_query.first);
	//assign variables
	vector<string> defination;
	explode(query, ";", &defination);	





	for(size_t i=0;i<defination.size();i++){
		temp=trim(defination[i]);
		//cout<<temp<<endl;
		vector<string> param;
		//explode(temp," ",&param);
		//paramType=trim(param[0]);
		
		p=temp.find_first_of(" ");
		paramType=temp.substr(0,p);
		toLowerCase(paramType);

		if(paramType=="stmt"||paramType=="prog_line"){
			paramType="statement";
		}else if(paramType=="assignment"){
			paramType="assign";
		}

		paramType=capitalize(paramType);

		//v
		if(validate.check_param_type(paramType)==false){
			cout<<paramType+" type not allowed"<<endl;
			return false;
		}


		temp=trim(temp.substr(p));

		//p=param[1].find(",");
		p=temp.find(",");

		
		if(p>0&&p<10){
			vector<string> subParam;
			//explode(param[1],",",&subParam);
			explode(temp,",",&subParam);
			for(size_t j=0;j<subParam.size();j++){

				args[trim(subParam[j])]=paramType;

			}
		
		}else{
			args[trim(temp)]=paramType;
		}
	}
	/*
	   for (map<string,string>::iterator it=args.begin(); it!=args.end(); ++it){
		  cout<<it->first+","+it->second<<endl;
	  }*/
	//Select a such that Follows (w, a) pattern a (“x”,_)
	query=trim(_query.second);
	temp=query;
	toLowerCase(temp);

	//check query
	p=temp.find("select");
	if(p>=0&&p<100) select_p=p;
	p=temp.find("such");
	if(p>0&&p<100) function_p=p;
	p=temp.find("pattern");
	if(p>0&&p<100) pattern_p=p;
	p=temp.find("with");
	if(p>0&&p<100) with_p=p;



	if(function_p==0&&pattern_p==0&&with_p==0){
		select_query=query.substr(0);
		body_query="";
	}else{
		vector<int> pos;

		if(function_p>0){
			pos.push_back(function_p);
		}

		if(pattern_p>0){
			pos.push_back(pattern_p);
		}

		if(with_p>0){
			pos.push_back(with_p);
		}
		int min_p=100000;

		for(size_t m=0;m<pos.size();m++){
			if (min_p>pos.at(m)){
				min_p=pos.at(m);
			}
		}


		select_query=query.substr(0,min_p);

		//body_query=temp.substr(min_p);
		body_query=query.substr(min_p);


	}
	
	body_query=replace(body_query,"such that","|");
	body_query=replace(body_query,"with ","| with (");
	body_query=replace(body_query," and ","| and");
	body_query=replace(body_query,"pattern","| pattern");

	//cout<<select_query<<endl;

	select_query=trim(select_query);

	if(select_query!=""){
		temp=select_query.substr(0,6);
		toLowerCase(temp);

		//v
		if(validate.check_select(temp)==false){
			cout << "no select" <<endl;
			return false;
		}

		temp=select_query.substr(6);

		//get selected arg
		temp=trim(temp);

		selectQuery_t select;
		string tempCall;
		//cout<<"tata "+temp<<endl;
		if(temp=="BOOLEAN"){
			select.SelectType="Boolean";
			selectType=3;
		}else{
			p=temp.find("<");
			if(p>=0&&p<100){
				temp=temp.substr(1);
				temp=temp.substr(0,temp.size()-1);
				vector<string> subTuple;
				explode(temp,",",&subTuple);
				selectType=5;
				string tempS;
				for(size_t j=0;j<subTuple.size();j++){
					tempS=subTuple.at(j);
					tempS=trim(tempS);
					temp=tempS;
					tempS=convertName(tempS,args);

					//v
					if(validate.check_no_bool(tempS)==false){
						 cout<<"No BOOLEAN allowed in tuple"<<endl;
						 return false;
					}

					if(tempS=="CallProc"){
						size_t z=temp.find(".");
						if((z>0&&z<20)) {
							select.tupleName.push_back(temp.substr(0,z));
						}else{
							select.tupleName.push_back(temp);
						}
						select.tupleType.push_back(tempS);
						temp=splitString(temp,0);
						sync.insert(temp);
					}else{
						if(validate.check_type_exist(args[tempS])==false){
							cout<<tempS+" no declared"<<endl;
							return false;
						}

						select.tupleName.push_back(tempS);
						
						tempType=args[tempS];
						toLowerCase(tempType);
						if(tempType=="stmtlst"){
							select.tupleType.push_back("StmtLst");
						}else if(tempType=="plus"){
							select.tupleType.push_back("+");
						}else if(tempType=="minus"){
							select.tupleType.push_back("-");
						}else if(tempType=="times"){
							select.tupleType.push_back("*");
						}else{
							select.tupleType.push_back(args[tempS]);
						}
					}

					if(args[tempS]=="Call"){
						toLowerCase(tempS);
						sync.insert(tempS);
					}
					//cout<<select.tupleType.at(j)+"->"+select.tupleName.at(j)<<endl;
				}
				select.SelectType="tuple";
			}else{
				//for call
				tempCall=temp;
		
				temp=convertName(temp,args);

				if(temp=="CallProc"){
					select.SelectType="CallProc";
				}else{
					select.SelectType=args[temp];
				}
			
				if(select.SelectType=="Procedure"||select.SelectType=="CallProc"){
					selectType=4;
				}else if(select.SelectType=="Variable"){
					selectType=2;
				}else if(select.SelectType=="Constant"){
					selectType=6;
				}else{
					selectType=1;
				}

				tempType=args[temp];
				toLowerCase(tempType);
				if(tempType=="stmtlst"){
					select.SelectType="StmtLst";
				}else if(tempType=="plus"){
					select.SelectType="+";
				}else if(tempType=="minus"){
					select.SelectType="-";
				}else if(tempType=="times"){
					select.SelectType="*";
				}
			}
		}
		select.SelectName=temp;
		selectedArgName=temp;
		if(temp=="CallProc"){
			select.SelectName=tempCall;
			selectedArgName=tempCall;

			temp=splitString(tempCall,0);
			sync.insert(temp);
		}
		


		if(args[temp]=="Call"){
			temp=splitString(tempCall,0);		
			toLowerCase(temp);
			sync.insert(temp);
		}

		if(validate.check_type_exist(select.SelectType)==false){
			cout<<"Parameter is not declared"<<endl;
			return false;
		}

		queries.selectQuery=select;


		//isSelectLineNum=true;
		//if(select.SelectType=="Variable") isSelectLineNum=false;
		//cout<<"select:=============="<<endl;
		//cout<< select.SelectType+","+select.SelectName+",";
		//cout<< <<endl;

		//if(function_p==0&&pattern_p==0) return true;
	}

	//cout<<body_query<<endl;

	vector<string> subQuery;
	explode(body_query, "|", &subQuery);	


	//cout<<queries.size()<<endl;
				stFunc.insert("follows");
			stFunc.insert("follows*");
			stFunc.insert("affects");
			stFunc.insert("affects*");
			stFunc.insert("affectsbip");
			stFunc.insert("affectsbip*");
			stFunc.insert("parent");
			stFunc.insert("parent*");
			stFunc.insert("next");
			stFunc.insert("next*");
			stFunc.insert("nextbip");
			stFunc.insert("nextbip*");

			otFunc.insert("contains");
			otFunc.insert("contains*");
			otFunc.insert("modifies");
			otFunc.insert("uses");
			otFunc.insert("calls");
			otFunc.insert("calls*");
	if(subQuery.size()>0){
		string possibleType;

		for(size_t i=0;i<subQuery.size();i++){
			temp=trim(subQuery[i]);

			if(temp.substr(0,3)=="and"){
				temp=temp.substr(3);
				temp=trim(temp);

				subQuery[i]=temp;

				p=temp.find("(");

				if(p>=0&&p<100){
					tempName=temp.substr(0,p);
					tempName=trim(tempName);
					toLowerCase(tempName);

					if((stFunc.find(tempName)==stFunc.end())||otFunc.find(tempName)==otFunc.end()){
						possibleType="pattern";
					}
				}else{
					possibleType="with";
				}



				if(i>0){
					if(subQuery[i-1].substr(0,4)=="with"&&possibleType=="with"){
						subQuery[i]="with ("+temp;
					}else if(subQuery[i-1].substr(0,7)=="pattern"&&possibleType=="pattern"){
						subQuery[i]="pattern "+temp;
					}
				}
			}



		}



		for(size_t i=0;i<subQuery.size();i++){
			temp=trim(subQuery[i]);
			//cout<<temp<<endl;
			p=temp.find("(");

			if(p>=0&&p<100){
				tempName=temp.substr(0,p);
			}
			tempName=trim(tempName);

			toLowerCase(tempName);



			if((stFunc.find(tempName)!=stFunc.end())||otFunc.find(tempName)!=otFunc.end()){		
				funcQuery_t func;
				func.FunctionType=trim(tempName);

				temp=temp.substr(p+1);
				p1=temp.find(",");
				func.FirstElementName=temp.substr(0,p1);
				func.FirstElementName=trim(func.FirstElementName);

				temp=temp.substr(p1+1);
				
				p1=temp.find(",");
				//v
				if(p1>=0&&p1<100){
					cout<<"Too many Parameter"<<endl;
					return false;
				}

				p1=temp.find(")");
				func.SecondElementName=temp.substr(0,p1);
				func.SecondElementName=trim(func.SecondElementName);

				char *check = (char*)func.FirstElementName.c_str();
				if(!isdigit(check[0])){	

					if(func.FirstElementName=="_"){
						func.FirstElementType="Statement";
					}else if((func.FirstElementName.substr(0,1)=="\"")&&(otFunc.find(tempName)!=otFunc.end())){
						func.FirstElementName=filterQuote(func.FirstElementName);
						func.FirstElementType="String";
					}else{
						func.FirstElementName=convertName(func.FirstElementName,args);
						func.FirstElementType=args[func.FirstElementName];
					}
				}else{
					if(tempName=="contains"||tempName=="contains*"){
						func.FirstElementType="Integer";
					}else{
						func.FirstElementType="Constant";
					}
				}
				tempType=func.FirstElementType;
				toLowerCase(tempType);

				if(tempType=="plus"){
					func.FirstElementType="+";
				}else if(tempType=="times"){
					func.FirstElementType="*";
				}else if(tempType=="minus"){
					func.FirstElementType="-";
				}else if(tempType=="stmtlst"){
					func.FirstElementType="StmtLst";
				}else if(tempType=="call"){
					temp=splitString(func.FirstElementName,0);		
					toLowerCase(temp);
					sync.insert(temp);
				}

				check = (char*)func.SecondElementName.c_str();
				if(!isdigit(check[0])){

					if(tempName=="modifies"||tempName=="uses"||tempName=="modifies*"||tempName=="uses*"){
						if(func.SecondElementName!="_"){
							if(func.SecondElementName.substr(0,1)!="\""){
								func.SecondElementType="Variable";
							}else if(func.SecondElementName.substr(0,1)=="\""){
									func.SecondElementName=filterQuote(func.SecondElementName);
									func.SecondElementType="String";
							}else{
								func.SecondElementType="Expression";
								func.SecondElementName=filterQuote(func.SecondElementName);
								func.SecondElementName=filterDash(func.SecondElementName);
							}
						}else{
							func.SecondElementType="Statement";
						}
					}else if(func.SecondElementName=="_"){
						func.SecondElementType="Statement";
					}else if((func.SecondElementName.substr(0,1)=="\"")&&(tempName=="calls"||tempName=="calls*"||tempName=="contains"||tempName=="contains*")){
						func.SecondElementName=filterQuote(func.SecondElementName);
						func.SecondElementType="String";
					}else{
						func.SecondElementName=convertName(func.SecondElementName,args);
						func.SecondElementType=args[func.SecondElementName];
					}
				}else{
					if(tempName=="contains"||tempName=="contains*"){
						func.SecondElementType="Integer";
					}else{
						func.SecondElementType="Constant";
					}
				}


				tempType=func.SecondElementType;
				toLowerCase(tempType);

				if(tempType=="plus"){
					func.SecondElementType="+";
				}else if(tempType=="times"){
					func.SecondElementType="*";
				}else if(tempType=="minus"){
					func.SecondElementType="-";
				}else if(tempType=="stmtlst"){
					func.SecondElementType="StmtLst";
				}else if(tempType=="call"){
					temp=splitString(func.SecondElementName,0);		
					toLowerCase(temp);
					sync.insert(temp);
				}
				//v
				if((stFunc.find(func.FirstElementName)!=stFunc.end())||otFunc.find(func.FirstElementName)!=otFunc.end()||stFunc.find(func.SecondElementName)!=stFunc.end()||otFunc.find(func.SecondElementName)!=otFunc.end()){
					cout<<"Nested relationship no allowed"<<endl;
					return false;
				}
				//v
				if(validate.check_type_exist(func.FirstElementType)==false||validate.check_type_exist(func.SecondElementType)==false){
					cout<<"Variable is no declared"<<endl;
					return false;
				}
				//v
				if(validate.check_func(tempName,2,func.FirstElementType,func.SecondElementType)==false){
					cout<<tempName+" is not allowed to have these parameters type"<<endl;
					return false;
				}
				//cout<<"functions:============="<<endl;
				//cout<<func.FirstElementType+","+func.FirstElementName+","+func.FunctionType<<endl;
				//cout<<func.SecondElementType+","+func.SecondElementName+","+func.FunctionType<<endl;
				queries.funcQueries.push_back(func);
			}else if(tempName.substr(0,7)=="pattern"){


				
				tempName=tempName.substr(8);
				tempName=trim(tempName);

				patternQuery_t pattern;
				pattern.ElementName=tempName;
				
				pattern.ElementType=args[tempName];

				temp=temp.substr(p+1);
				p1=temp.find(",");
				pattern.VarRef=temp.substr(0,p1);
				pattern.VarRef=trim(pattern.VarRef);

				//v
				string pattern_arg1,pattern_arg2;

				if(pattern.VarRef.substr(0,1)=="\""||pattern.VarRef=="_"){
					pattern_arg1="string";
					pattern.isVarRefVariable=false;
					pattern.VarRef=trim(filterQuote(pattern.VarRef));
				}else{
					pattern_arg1="variable";
					pattern.isVarRefVariable=true;
				}

				/*
				if(pattern.isVarRefVariable==true)
					cout<<"var ref is true"<<endl;

				if(pattern.isVarRefVariable==false)
					cout<<"var ref is false"<<endl;
					*/
				temp=temp.substr(p1+1);

				string tempIf=pattern.ElementType;
				toLowerCase(tempIf);
				if(tempIf=="if"){
					p1=0;
					p1=temp.find(",");

					if(p1<0||p1>100){
						//cout<<"Wrong number of parameter for if function"<<endl;
						throw string("Some Var");
						return false;
					}
				}else{
					p1=temp.rfind(")");
				}
				temp=temp.substr(0,p1);
				temp=trim(temp);
				if(temp.substr(0,1)=="\""||temp.substr(0,1)=="_"){
					if(temp.substr(0,1)=="_"){
						pattern.ExpWithUnderscore=true;
						pattern_arg2="_";
					}else{
						pattern.ExpWithUnderscore=false;
						pattern_arg2="string";
					}
					temp=filterQuote(temp);
					temp=filterDash(temp);
				}
				temp=trim(temp);

				stack<char> op_stack;
				//string infix="1+3*2/4";
				//ststring infix="2*3+1-4
				string input=temp;

				if(input.length()>1){
					string infix="";

					int m=0;
					vector<string> patternVars;
					
					string subString="";
					string ch;

					while(input!=""){
						/*
						p1=findOp(input);
						if(p1>0&&p1<1000){
							patternVars.push_back(trim(input.substr(0,p1)));
							infix+=convertInt(m)+trim(input.substr(p1,1));
							input=input.substr(p1+1);
						}else{
							patternVars.push_back(trim(input));
							input="";
							infix+=conviertInt(m);
						}
						m++;*/
	
						ch=input.substr(0,1);
						if(ch=="+"||ch=="-"||ch=="*"||ch=="/"||ch=="("||ch==")"){
							if(subString!=""){
								patternVars.push_back(trim(subString));
								infix+=convertInt(m);
								subString="";
								m++;
							}
							infix+=trim(ch);
							
						}else{
							subString=subString+ch;
						}
						input=input.substr(1);
						input=trim(input);
					}
					if(subString!=""){
						patternVars.push_back(trim(subString));
						infix+=convertInt(m);
						subString="";
					}					
					//cout<<"-----------------------------i am infix  "+infix<<endl;
					/*
					for(int i=0; i<patternVars.size(); i++){
						cout<<patternVars.at(i)<<endl;
					}

					cout<<"infix:"+infix<<endl;
					*/
					string output;

					for (unsigned i = 0; i < infix.length(); i++) {
						//cout<<i<<endl;
						if (infix[i] == '+' || infix[i] == '-' || infix[i] == '*' || infix[i] == '/') {
							while (!op_stack.empty() && priority(op_stack.top()) <= priority(infix[i])) {
								output.push_back(op_stack.top());
								op_stack.pop();
							}
							op_stack.push(infix[i]);
						} else if (infix[i] == '(') {
							op_stack.push(infix[i]);
						} else if (infix[i] == ')') {
							while (op_stack.top() != '(') {
								output.push_back(op_stack.top());
								op_stack.pop();
							}
							op_stack.pop();
						}else{
							output.push_back(infix[i]);
						}
					}

					while (!op_stack.empty()) {
						output.push_back(op_stack.top());
						op_stack.pop();
					}
			
					//cout<<"i am output +++++++++++  "+output;

					std::reverse(output.begin(), output.end());

					vector<Pattern_node> qs;
					vector<int> os;
					int y=0;

					

					while(output!=""){
						Pattern_node temp;
						temp.setData(output.substr(0,1));
						//temp.data=output.substr(0,1);
						if(os.size()>0){
							int d=os.size();
							while(d>0){
								d=d-1;
								int osIndex=os.at(d);
								if(qs.at(osIndex).getRight()==0){
									qs.at(osIndex).setRight(y);
									break;
								}else if(qs.at(osIndex).getLeft()==0){
									qs.at(osIndex).setLeft(y);
									break;
								}
							}
						}
						//if(temp.getData()=="+"||temp.getData()=="-"||temp.getData()=="/"||temp.getData()=="*"){
						//temp.setRight(0);
						//temp.setLeft(0)
						if(temp.getData()=="+"||temp.getData()=="-"||temp.getData()=="/"||temp.getData()=="*"){
							temp.setRight(0);
							temp.setLeft(0);
							os.push_back(y);
						}else{
							
							int varIndex=atoi(temp.getData().c_str());
							temp.setData(patternVars.at(varIndex));

							temp.setRight(-1);
							temp.setLeft(-1);

						}
						qs.push_back(temp);

						output=output.substr(1);
						y++;
					}
					
					
					/*
					for(int j=0; j<qs.size(); j++){
						cout<<qs.at(j).data<<endl;
						cout<<"right:"+convertInt(qs.at(j).right)+",left:"+convertInt(qs.at(j).left)<<endl;
					}*/

					//cout<<output<<endl;

					pattern.Expression=qs;
				}else{
				
					if(input!="_"){
						Pattern_node ex;
						ex.setData(input);
						pattern.Expression.push_back(ex);
					}
				}

					//v

				if(validate.check_pattern(pattern.ElementType,pattern_arg1,pattern_arg2)==false){
					cout<<"Pattern is not in correct format"<<endl;
					return false;
				}			


				queries.patternQueries.push_back(pattern);
				
				

	

			}else if(tempName=="with"){
				compareQuery_t compare;

				temp=temp.substr(p+1);
				temp=trim(temp);

				string with_arg1,with_attr1,with_arg2,with_attr2;

				p1=temp.find("=");
					
				if(p1<0||p1>100){
					cout<<"False with"<<endl;
					return false;
				}
				

				vector<string> subWith;
				explode(temp,"=",&subWith);

				temp=subWith.at(0);
				temp=trim(temp);
                //temp=filterQuote(temp);
                //temp=trim(temp);
								
				p1=temp.find(".");
				if(p1>=0&&p1<100){
					//temp=temp.substr(0,p1);
					temp=trim(temp);
					compare.leftName=temp;
					compare.leftName=trim(convertName(compare.leftName,args));

					if(compare.leftName=="CallProc"){
						//compare.leftName=temp.substr(0,p1);
						//toLowerCase(temp);
						compare.leftName=temp;
						compare.leftType="CallProc";
					}else{
						compare.leftType=args[compare.leftName];
					}
					
					if(compare.leftType=="Stmt"||compare.leftType=="Prog_line"){
						compare.leftType="Statement";
					}
					with_attr1=temp.substr(p1+1);
				}else{
					if (is_digit(temp[0])){
						compare.leftName=temp;
						compare.leftType="Integer";
					}else{
						if(temp.substr(0,1)=="\""){
							compare.leftName=filterQuote(temp);
							compare.leftType="String";
						}else{
							compare.leftName=temp;
							compare.leftType=args[temp];
						}
					}
					with_attr1="";
				}

				//check sync
				if(compare.leftType=="Call"||compare.leftType=="CallProc"){
					string syncItem=splitString(compare.leftName,0);
					
					if(sync.find(syncItem)!=sync.end()){
						
						queries.callRelation.push_back(syncItem);
					}
				}
				with_arg1=compare.leftType;
				temp=subWith.at(1);
				temp=trim(temp);
                //temp=filterQuote(temp);
                //temp=trim(temp);
				p1=temp.find(".");
				if(p1>=0&&p1<100){
					//temp=temp.substr(0,p1);
					temp=trim(temp);
					compare.rightName=temp;
					compare.rightName=trim(convertName(compare.rightName,args));
					
					if(compare.rightName=="CallProc"){
						//compare.rightName=temp.substr(0,p1);
						toLowerCase(temp);
						compare.rightName=temp;
						compare.rightType="CallProc";
					}else{
						compare.rightType=args[compare.rightName];
					}

					if(compare.rightType=="Stmt"||compare.rightType=="Prog_line"){
						compare.rightType="Statement";
					}
					with_attr2=temp.substr(p1+1);

				}else{
					if (is_digit(temp[0])){
						compare.rightName=temp;
						compare.rightType="Integer";
					}else{
						if(temp.substr(0,1)=="\""){
							compare.rightName=filterQuote(temp);
							compare.rightType="String";
						}else{
							compare.rightName=temp;
							compare.rightType=args[temp];
						}
					}
					with_attr2="";
				}


				
				//check sync
				if(compare.rightType=="Call"||compare.rightType=="CallProc"){
					string syncItem=splitString(compare.rightName,0);
					
					if(sync.find(syncItem)!=sync.end()){
						
						queries.callRelation.push_back(syncItem);
					}
				}
				with_arg2=compare.rightType;
				if(validate.check_with(with_arg1,with_attr1,with_arg2,with_attr2)==false){
					cout<<"With is not is a correct format"<<endl;
					return false;
				}
				//cout<<"with: =============="<<endl;
				//cout<<compare.leftType+","+compare.leftName+","+compare.rightType+","+compare.rightName<<endl;
				queries.compareQueries.push_back(compare);
			}
		}
	}
	return true;

}



// Query Preprocessor funtions for building table
queryTreeNode_t QueryProcessor::buildAndMergeTable(){
	if(queries.selectQuery.SelectType != "Boolean")
		preBuildSelect(queries.selectQuery);

	for(int i=0;i<queries.funcQueries.size();i++){
		// Query Follows
		if(queries.funcQueries.at(i).FunctionType == "follows")
			preQueryFollows(queries.funcQueries.at(i),i);
		// Query Follows*
		else if(queries.funcQueries.at(i).FunctionType == "follows*")
			preQueryFollowsStar(queries.funcQueries.at(i),i);
		// Query Parent
		else if(queries.funcQueries.at(i).FunctionType == "parent")
			preQueryParent(queries.funcQueries.at(i),i);
		// Query Parent*
		else if(queries.funcQueries.at(i).FunctionType == "parent*")
			preQueryParentStar(queries.funcQueries.at(i),i);
		// Query Modifies
		else if(queries.funcQueries.at(i).FunctionType== "modifies")
			preQueryModifies(queries.funcQueries.at(i),i);
		// Query Uses
		else if(queries.funcQueries.at(i).FunctionType == "uses")
			preQueryUses(queries.funcQueries.at(i),i);
		// Call
		else if(queries.funcQueries.at(i).FunctionType == "calls")
			preQueryCall(queries.funcQueries.at(i),i);
		else if(queries.funcQueries.at(i).FunctionType == "calls*")
			preQueryCallStar(queries.funcQueries.at(i),i);
		// Next
		else if(queries.funcQueries.at(i).FunctionType == "next")
			preQueryNext(queries.funcQueries.at(i),i);
		// Next*
		else if(queries.funcQueries.at(i).FunctionType == "next*"){
			if((*pkb).getNextStarList().empty())
				computeNextStar();
			preQueryNextStar(queries.funcQueries.at(i),i);
		}
		// NextBip
		else if(queries.funcQueries.at(i).FunctionType == "nextbip")
			preQueryNextBip(queries.funcQueries.at(i),i);
		// NextBip*
		else if(queries.funcQueries.at(i).FunctionType == "nextbip*"){
			if((*pkb).getNextStarMatrix().empty())
				computeNextStar();
			if((*pkb).getNextBipStarList().empty())
				computeNextBipStar();
			preQueryNextBipStar(queries.funcQueries.at(i),i);
		}
		// Affects
		else if(queries.funcQueries.at(i).FunctionType == "affects"){
			if((*pkb).getAffectsMatrix().empty())
				computeAffects();
			preQueryAffects(queries.funcQueries.at(i),i);
		}
		// Affects*
		else if(queries.funcQueries.at(i).FunctionType == "affects*"){
			if((*pkb).getAffectsMatrix().empty())
				computeAffects();
			if((*pkb).getAffectsStarMatrix().empty())
				computeAffectsStar();
			preQueryAffectsStar(queries.funcQueries.at(i),i);
		}
		// AffectsBip
		else if(queries.funcQueries.at(i).FunctionType == "affectsbip"){
			if(!affectsBip.IsAffectsBipComputed())
				affectsBip.ComputeAffectsBip();
			preQueryAffectsBip(queries.funcQueries.at(i),i);
		}
		// AffectsBip*
		else if(queries.funcQueries.at(i).FunctionType == "affectsbip*"){
			if(!affectsBip.IsAffectsBipComputed())
				affectsBip.ComputeAffectsBip();
			if(!affectsBip.IsAffectsBipStarComputed())
				affectsBip.ComputeAffectsBipStar();
			preQueryAffectsBipStar(queries.funcQueries.at(i),i);
		}
		// Contains
		else if(queries.funcQueries.at(i).FunctionType == "contains"){
			preQueryContains(queries.funcQueries.at(i), i);
		}
		// Contains*
		else if(queries.funcQueries.at(i).FunctionType == "contains*"){
			preQueryContainsStar(queries.funcQueries.at(i), i);
		}
	}

	// Query Pattern
	for(int i=0;i<queries.patternQueries.size();i++)
		preQueryPattern(queries.patternQueries.at(i),i);

	// Query comparison
	for(int i=0;i<queries.compareQueries.size();i++)
		preQueryCompare(queries.compareQueries.at(i),i);

	// Call stmt# and procName relationship
	for(int i=0;i<queries.callRelation.size();i++)
		preBuildCallRelationTable(queries.callRelation.at(i),i);
	//------------------------------------------------------------

	VarTable varTable = (*pkb).getVarTable();
	ProcTable procTable = (*pkb).getProcTable();
	queryTreeNode_t finalTable;
	vector<int> inTree;
	vector<vector<int>> orderTree;
	vector<int> rootNodesInOrderTree;
	vector<vector<int>> majorTreeList;
	int majorCount = 0;
	vector<vector<int>> normalTreeList;
	int normalCount = 0;
	//remove useless comumn
	vector<string> colName;
	vector<int> colCount;
	//find the column names we select
	vector<string> selectList;

	if(queryTree.size()>1){
		for(int i=0;i<queryTree.size();i++){
			if(queryTree.at(i).type.compare("Select")==0){
				selectList.push_back(queryTree.at(i).colName.at(0));
			}
		}
		//-------------
		//when with pass a table with numOfcolumn = 0
		bool withFalse = false;
		for(int iy=0;iy<queryTree.size();iy++){
			if(queryTree.at(iy).numOfColumn==0){
				withFalse = true;
				break;
			}
		}
		//---------------------
		for(int i=0;i<queryTree.size();i++){
			inTree.push_back(0);
			orderTree.push_back(vector<int>());
		}

		for(int i=0;i<queryTree.size();i++){
			if(inTree.at(i)==0){
				rootNodesInOrderTree.push_back(i);
				inTree.at(i)=1;
				bool isInMajprTree = false;
				if(queryTree.at(i).type.compare("Select")==0)
					isInMajprTree = true;
				buildNodeIntoTree(i,queryTree,&inTree,&orderTree,isInMajprTree, majorCount,&majorTreeList,normalCount, &normalTreeList);
				if(isInMajprTree){
					majorCount++;
				} else{
					normalCount++;
				}
			}
		}
		//deal with column counting, for the follwing step, first build table check if empty. if has with a = 3, replace. 
		//then remove "_","3" and "a","a", and the column appear one not selected
		for(int cc=0;cc<queryTree.size();cc++){
			for(int cd=0;cd<queryTree.at(cc).numOfColumn;cd++){
				if((queryTree.at(cc).colName.at(cd).compare("_")!=0)&&(
					!isdigit(queryTree.at(cc).colName.at(cd)[0]))){
					bool contain = false;
					int ce;
					for(ce=0;ce<colName.size();ce++){
						if(colName.at(ce).compare(queryTree.at(cc).colName.at(cd))==0){
							contain = true;
							break;
						}
					}
					if(contain==false){
						colName.push_back(queryTree.at(cc).colName.at(cd));
						colCount.push_back(1);
					}else{
						colCount.at(ce)++;
					}
				}
			}
		}
		//build and merge
		switch(selectType){
		case 1:case 2:case 4:case 5:case 6:{
			vector<queryTreeNode_t> majorResult;
			bool NeedMajor = true;
			vector<int> toMerge;
			//first deal with normal tree
			for(int i=0;i<rootNodesInOrderTree.size();i++){
				if(!queryTree.at(rootNodesInOrderTree.at(i)).type.compare("Select")==0){
					toMerge = vector<int> ();
					orderOfMajorTree(rootNodesInOrderTree.at(i),orderTree,&toMerge);
					StmtTable st = (*pkb).getStmtTable();
					//@yaoxin build queryTree.at(rootNodesInOrderTree.at(i)), this one is the first one in this group, if empty, NeedMajor=false,break;
					finalTable.numOfColumn = 0;
					buildTable(rootNodesInOrderTree.at(i), finalTable);
					if(queryTree.at(rootNodesInOrderTree.at(i)).numOfColumn==0||queryTree.at(rootNodesInOrderTree.at(i)).table.at(0).empty()){
						NeedMajor = false;
						break;
					}
					//remove case like "a", "a", "_". "6". appear once but not selected of built table,projection
					queryTree.at(rootNodesInOrderTree.at(i))= firstRemove(queryTree.at(rootNodesInOrderTree.at(i)));
					finalTable = queryTree.at(rootNodesInOrderTree.at(i));
					//build rest tables using the result of finalTable
					int buildCount = 0;
					while(buildCount<toMerge.size()){
						//@yaoxin build	queryTree.at(toMerge.at(buildCount)),if empty, NeedMajor=false,break;2 cases
						//remove case like "a", "a", "_". "6". appear once but not selected of built table,projection
						buildTable(toMerge.at(buildCount), finalTable);
						if(queryTree.at(toMerge.at(buildCount)).numOfColumn==0||queryTree.at(toMerge.at(buildCount)).table.at(0).empty()){
							NeedMajor = false;
							break;
						}
						queryTree.at(toMerge.at(buildCount)) = firstRemove(queryTree.at(toMerge.at(buildCount)));
						if(queryTree.at(toMerge.at(buildCount)).numOfColumn>0){
							finalTable =  mergeTable(finalTable,queryTree.at(toMerge.at(buildCount)));
							if((finalTable.numOfColumn>0)&&(finalTable.table.at(0).size()==0)){
								NeedMajor = false;
								break;
							}
							if(finalTable.numOfColumn>1){
								for(int st=0;st<commonCol.size();st++){
									for(int sw=0;sw<colName.size();sw++){
										if(commonCol.at(st).compare(colName.at(sw))==0){
											colCount.at(sw)--;
											if(colCount.at(sw)<=0){
												//remove
												int ts;
												for(ts=0;ts<selectList.size();ts++){
													if(selectList.at(ts).compare(colName.at(sw))==0)
														break;
												}
												if(ts==selectList.size()&&finalTable.numOfColumn>1){
													//sure to remove
													for(int th=0;th<finalTable.numOfColumn;th++){
														if(finalTable.colName.at(th).compare(colName.at(sw))==0){
															finalTable.numOfColumn--;
															finalTable.colName.erase(finalTable.colName.begin()+th);
															finalTable.table.erase(finalTable.table.begin()+th);
															for(int ti=0;ti<finalTable.table.at(0).size();ti++){
																for(int to=ti+1;to<finalTable.table.at(0).size();to++){
																	bool finalEq = true;
																	for(int tp=0;tp<finalTable.numOfColumn;tp++){
																		if(finalTable.table.at(tp).at(ti)!=finalTable.table.at(tp).at(to)){
																			finalEq = false;
																			break;
																		}
																	}
																	if(finalEq==true){
																		for(int tf=0;tf<finalTable.numOfColumn;tf++){
																			finalTable.table.at(tf).erase(finalTable.table.at(tf).begin()+to);
																		} 
																	}
																}
															}
															break;
														}

													}
												}
											}
											break;
										}
									}
								}
							}
						}
						buildCount++;
					}
				}
			}
			if(NeedMajor ==false){
				finalTable.numOfColumn = 0;
			}else{
				//deal with majorTree
				for(int i=0;i<rootNodesInOrderTree.size();i++){
					if(queryTree.at(rootNodesInOrderTree.at(i)).type.compare("Select")==0){
						toMerge = vector<int> ();
						orderOfMajorTree(rootNodesInOrderTree.at(i),orderTree,&toMerge);
						int dc; 
						//vector<int> replaceWith;// find any "with a=3" or "with 3=a", if a is selected, it is a special case
						//@yaoxin replace with, if after replace table is empty, NeedMajor=false,break;

						//@yaoxin build queryTree.at(rootNodesInOrderTree.at(i)), this one is the first one in this group, if empty, NeedMajor=false,break;
						//remove case like "a", "a", "_". "6". appear once but not selected of built table,projection
						buildTable(rootNodesInOrderTree.at(i), finalTable);
						
						if(queryTree.at(rootNodesInOrderTree.at(i)).numOfColumn==0||queryTree.at(rootNodesInOrderTree.at(i)).table.at(0).empty()){
							NeedMajor =false;
							break;
						}
						//build rest tables using the result of finalTable
						queryTree.at(rootNodesInOrderTree.at(i)) = firstRemove(queryTree.at(rootNodesInOrderTree.at(i)));
						finalTable = queryTree.at(rootNodesInOrderTree.at(i));
						int buildCount=0;
						while(buildCount<toMerge.size()){
							//@yaoxin build	queryTree.at(toMerge.at(buildCount)),if empty, NeedMajor=false,break;
							//remove case like "a", "a", "_". "6". appear once but not selected of built table,projection
							buildTable(toMerge.at(buildCount), finalTable);
							if(queryTree.at(toMerge.at(buildCount)).numOfColumn==0||queryTree.at(toMerge.at(buildCount)).table.at(0).empty()){
								NeedMajor =false;
								break;
							}
							queryTree.at(toMerge.at(buildCount)) = firstRemove(queryTree.at(toMerge.at(buildCount)));
							if(queryTree.at(toMerge.at(buildCount)).numOfColumn>0){
								finalTable =  mergeTable(finalTable,queryTree.at(toMerge.at(buildCount)));
								if((finalTable.numOfColumn>0)&&(finalTable.table.at(0).size()==0)){
									NeedMajor = false;
									break;
								}
								if(finalTable.numOfColumn>1){
									for(int st=0;st<commonCol.size();st++){
										for(int sw=0;sw<colName.size();sw++){
											if(commonCol.at(st).compare(colName.at(sw))==0){
												colCount.at(sw)--;
												if(colCount.at(sw)<=0){
													//remove
													int ts;
													for(ts=0;ts<selectList.size();ts++){
														if(selectList.at(ts).compare(colName.at(sw))==0)
															break;
													}
													if(ts==selectList.size()&&finalTable.numOfColumn>1){
														//sure to remove
														for(int th=0;th<finalTable.numOfColumn;th++){
															if(finalTable.colName.at(th).compare(colName.at(sw))==0){
																finalTable.numOfColumn--;
																finalTable.colName.erase(finalTable.colName.begin()+th);
																finalTable.table.erase(finalTable.table.begin()+th);
																for(int ti=0;ti<finalTable.table.at(0).size();ti++){
																	for(int to=ti+1;to<finalTable.table.at(0).size();to++){
																		bool finalEq = true;
																		for(int tp=0;tp<finalTable.numOfColumn;tp++){
																			if(finalTable.table.at(tp).at(ti)!=finalTable.table.at(tp).at(to)){
																				finalEq = false;
																				break;
																			}
																		}
																		if(finalEq==true){
																			for(int tf=0;tf<finalTable.numOfColumn;tf++){
																				finalTable.table.at(tf).erase(finalTable.table.at(tf).begin()+to);
																			} 
																		}
																	}
																}
																break;
															}

														}
													}
												}
												break;
											}
										}
									}
								}
							}
							buildCount++;
						}
						if(NeedMajor == false){
							break;
						}
						majorResult.push_back(finalTable);
					}
				}
				if(NeedMajor==false||majorResult.empty()){
					finalTable.numOfColumn=1;
					finalTable.table = vector<vector<int>>();
					finalTable.table.push_back(vector<int>());
				}else{
					finalTable = majorResult.at(0);
					for(int i=1;i<majorResult.size();i++){
						finalTable =  mergeTable(finalTable,majorResult.at(i));
						//remove duplicate
						if(finalTable.numOfColumn>1){
							for(int yf=0;yf<finalTable.table.at(0).size();yf++){
								for(int yg=yf+1;yg<finalTable.table.at(0).size();yg++){
									bool twoAreEQ = true;
									for(int gu=0;gu<finalTable.numOfColumn;gu++){
										if(finalTable.table.at(gu).at(yf)!=finalTable.table.at(gu).at(yg)){
											twoAreEQ=false;
											break;
										}
									}
									if(twoAreEQ == true){
										for(int gu=0;gu<finalTable.numOfColumn;gu++){
											finalTable.table.at(gu).erase(finalTable.table.at(gu).begin()+yg);
										}
									}
								}
							}
						}
						//-----------
					}
				}
			}
			break;
			   }
		case 3:{
			bool returnFalse =false;
			vector<queryTreeNode_t> majorResult;
			vector<int> toMerge;
			for(int i=0;i<rootNodesInOrderTree.size();i++){
				if(!queryTree.at(rootNodesInOrderTree.at(i)).type.compare("Select")==0){
					toMerge = vector<int> ();
					orderOfMajorTree(rootNodesInOrderTree.at(i),orderTree,&toMerge);
					StmtTable st = (*pkb).getStmtTable();
					int da; 

					//@yaoxin build queryTree.at(rootNodesInOrderTree.at(i)), this one is the first one in this group, if empty,returnFalse=true,break;
					finalTable.numOfColumn = 0;
					finalTable.table=vector<vector<int>>();
					buildTable(rootNodesInOrderTree.at(i), finalTable);
					if(queryTree.at(rootNodesInOrderTree.at(i)).numOfColumn==0||queryTree.at(rootNodesInOrderTree.at(i)).table.at(0).empty()){
						returnFalse = true;
						break;
					}
					//remove case like "a", "a", "_". "6". appear once but not selected of built table,projection
					queryTree.at(rootNodesInOrderTree.at(i)) = firstRemove(queryTree.at(rootNodesInOrderTree.at(i)));
					finalTable = queryTree.at(rootNodesInOrderTree.at(i));
					//build rest tables using the result of finalTable
					int buildCount = 0;
					while(buildCount<toMerge.size()){
						//@yaoxin build	queryTree.at(toMerge.at(buildCount)),if empty, NeedMajor=false,break;2 cases
						//remove case like "a", "a", "_". "6". appear once but not selected of built table,projection
						buildTable(toMerge.at(buildCount), finalTable);
						if(queryTree.at(toMerge.at(buildCount)).numOfColumn==0||queryTree.at(toMerge.at(buildCount)).table.at(0).empty()){
							returnFalse = true;
							break;
						}
						queryTree.at(toMerge.at(buildCount)) = firstRemove(queryTree.at(toMerge.at(buildCount)));
						if(queryTree.at(toMerge.at(buildCount)).numOfColumn>0){
							finalTable =  mergeTable(finalTable,queryTree.at(toMerge.at(buildCount)));
							if((finalTable.numOfColumn>0)&&(finalTable.table.at(0).size()==0)){
								returnFalse = true;
								break;
							}
							if(finalTable.numOfColumn>1){
								for(int st=0;st<commonCol.size();st++){
									for(int sw=0;sw<colName.size();sw++){
										if(commonCol.at(st).compare(colName.at(sw))==0){
											colCount.at(sw)--;
											if(colCount.at(sw)<=0){
												//remove
												int ts;
												for(ts=0;ts<selectList.size();ts++){
													if(selectList.at(ts).compare(colName.at(sw))==0)
														break;
												}
												if(ts==selectList.size()&&finalTable.numOfColumn>1){
													//sure to remove
													for(int th=0;th<finalTable.numOfColumn;th++){
														if(finalTable.colName.at(th).compare(colName.at(sw))==0){
															finalTable.numOfColumn--;
															finalTable.colName.erase(finalTable.colName.begin()+th);
															finalTable.table.erase(finalTable.table.begin()+th);
															for(int ti=0;ti<finalTable.table.at(0).size();ti++){
																for(int to=ti+1;to<finalTable.table.at(0).size();to++){
																	bool finalEq = true;
																	for(int tp=0;tp<finalTable.numOfColumn;tp++){
																		if(finalTable.table.at(tp).at(ti)!=finalTable.table.at(tp).at(to)){
																			finalEq = false;
																			break;
																		}
																	}
																	if(finalEq==true){
																		for(int tf=0;tf<finalTable.numOfColumn;tf++){
																			finalTable.table.at(tf).erase(finalTable.table.at(tf).begin()+to);
																		} 
																	}
																}
															}
															break;
														}

													}
												}
											}
											break;
										}
									}
								}
							}
						}
						buildCount++;
					}
				}
			}
			if(returnFalse==false){
				finalTable.numOfColumn=1;
				finalTable.table = vector<vector<int>>();
				finalTable.table.push_back(vector<int>());
				finalTable.table.at(0).push_back(-1);
			}else{
				finalTable.numOfColumn=1;
				finalTable.table = vector<vector<int>>();
				finalTable.table.push_back(vector<int>());
			}
			break;
			   }
		}

	}else{
		if(queryTree.size()==0){
			finalTable.numOfColumn =1;
			finalTable.type="with";
			finalTable.colName.push_back("with");
			finalTable.table = vector<vector<int>>();
			finalTable.table.push_back(vector<int>());
			finalTable.table.at(0).push_back(-1);
		}else{
			buildTable(0, finalTable);
			finalTable = queryTree.at(0);
		}
	}
	return finalTable;

}

void QueryProcessor::preBuildSelect(selectQuery_t q){
	/*
	AST ast = (*pkb).getAST();
	StmtTable st = (*pkb).getStmtTable();
	VarTable varTable = (*pkb).getVarTable();
	ProcTable procTable = (*pkb).getProcTable();
	ConstTable contTable = (*pkb).getConstTable();
	vector<int> callProc = (*pkb).getCalleeList();
	*/
	// Tuple
	if(q.SelectType == "tuple"){
		for(int i=0;i<q.tupleName.size();i++){
			queryTreeNode_t qtNode;
			qtNode.type = "Select";
			qtNode.numOfColumn = 1;
			qtNode.position=i;
			qtNode.colName.push_back(q.tupleName.at(i));
			/*
			vector<int> col1;
			if(q.tupleType.at(i) == "Procedure"){
			for(int j=0;j<procTable.getSize();j++)
			col1.push_back(j);
			}
			else if(q.SelectType == "CallProc"){
			for(int i=0;i<callProc.size();i++)
			col1.push_back(callProc.at(i));
			}
			else if(q.SelectType == "Constant"){
			for(int i=0;i<contTable.getSize();i++)
			col1.push_back(contTable.getConstant(i));
			}
			else if(q.tupleType.at(i) == "Variable"){
			for(int j=0;j<varTable.getSize();j++)
			col1.push_back(j);
			}
			else  if(q.tupleType.at(i) == "Statement")
			for(int j=1;j<=ast.getTotalLineNum();j++)
			col1.push_back(j);
			else
			for(int j=1;j<=ast.getTotalLineNum();j++)
			if(q.tupleType.at(i) == st.getLineDetails(j).type)
			col1.push_back(j);
			qtNode.table.push_back(col1);
			*/
			queryTree.push_back(qtNode);
			
		}
	}
	// Not tuple
	else{
		queryTreeNode_t qtNode;
		qtNode.type = "Select";
		qtNode.numOfColumn = 1;
		qtNode.position=-1;
		qtNode.colName.push_back(q.SelectName);
		/*
		vector<int> col1;
		if(q.SelectType == "Procedure"){
		for(int i=0;i<procTable.getSize();i++)
		col1.push_back(i);
		}
		else if(q.SelectType == "CallProc"){
		for(int i=0;i<callProc.size();i++)
		col1.push_back(callProc.at(i));
		}
		else if(q.SelectType == "Constant"){
		for(int i=0;i<contTable.getSize();i++)
		col1.push_back(contTable.getConstant(i));
		}
		else if(q.SelectType == "Variable"){
		for(int i=0;i<varTable.getSize();i++)
		col1.push_back(i);
		}
		else  if(q.SelectType == "Statement")
		for(int i=1;i<=ast.getTotalLineNum();i++)
		col1.push_back(i);
		else
		for(int i=1;i<=ast.getTotalLineNum();i++)
		if(q.SelectType == st.getLineDetails(i).type)
		col1.push_back(i);

		qtNode.table.push_back(col1
		*/
		queryTree.push_back(qtNode);
		
	}
}

void QueryProcessor::preQueryFollows(funcQuery_t q, int po){
	queryTreeNode_t qtNode;
	qtNode.type = "Follows";
	qtNode.numOfColumn = 2;
	qtNode.position = po;
	qtNode.colName.push_back(q.FirstElementName);
	qtNode.colName.push_back(q.SecondElementName);
	/*
	vector<int> col1, col2;

	int totalLineNum = (*pkb).getTotalLineNum();
	vector<pair<int,int>> list = (*pkb).getFollowsList();
	vector<vector<int>> matrix = (*pkb).getFollowsMatrix();

	AST ast = (*pkb).getAST();

	// Both args are constant.
	if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
	if(c1>totalLineNum || c2>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(matrix.at(c1).at(c2) == 1){
	col1.push_back(c1);
	col2.push_back(c2);	
	}
	}
	// First arg is constant.
	else if(q.FirstElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str());
	if(c1>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(q.SecondElementType.compare("Statement") == 0){
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(c1).at(i) == 1){
	col1.push_back(c1);
	col2.push_back(i);
	}
	}
	else{
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
	col1.push_back(c1);
	col2.push_back(i);
	}
	}
	}
	// Second arg is constant.
	else if(q.SecondElementType.compare("Constant") == 0){
	int c2 = atoi(q.SecondElementName.c_str());
	if(c2>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(q.FirstElementType.compare("Statement") == 0){
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(i).at(c2) == 1){
	col1.push_back(i);
	col2.push_back(c2);
	}
	}
	else{
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
	col1.push_back(i);
	col2.push_back(c2);
	}
	}
	}
	// Both arg are not constant.
	else{
	// Both arg are of statement type.
	if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
	if(	q.FirstElementName.compare("_") == 0 && q.SecondElementName.compare("_") == 0 || 
	q.FirstElementName.compare(q.SecondElementName) != 0	)
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// First arg is of statement type.
	else if(q.FirstElementType.compare("Statement") == 0){
	for(int i=0;i<list.size();i++)
	if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// Second arg is of statemnt type.
	else if(q.SecondElementType.compare("Statement") == 0){
	for(int i=0;i<list.size();i++)
	if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// Both args are not of the type statement.
	else{
	if(q.FirstElementName.compare(q.SecondElementName) != 0)
	for(int i=0;i<list.size();i++)
	if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
	q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	*/
	queryTree.push_back(qtNode);

}

void QueryProcessor::preQueryFollowsStar(funcQuery_t q, int po){
	queryTreeNode_t qtNode;
	qtNode.type = "Follows*";
	qtNode.numOfColumn = 2;
	qtNode.position=po;
	qtNode.colName.push_back(q.FirstElementName);
	qtNode.colName.push_back(q.SecondElementName);
	/*
	vector<int> col1, col2;

	int totalLineNum = (*pkb).getTotalLineNum();
	vector<pair<int,int>> list = (*pkb).getFollowsStarList();
	vector<vector<int>> matrix = (*pkb).getFollowsStarMatrix();

	AST ast = (*pkb).getAST();

	// Both args are constant.
	if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
	if(c1>totalLineNum || c2>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(matrix.at(c1).at(c2) == 1){
	col1.push_back(c1);
	col2.push_back(c2);	
	}
	}
	// First arg is constant.
	else if(q.FirstElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str());
	if(c1>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(q.SecondElementType.compare("Statement") == 0){
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(c1).at(i) == 1){
	col1.push_back(c1);
	col2.push_back(i);
	}
	}
	else{
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
	col1.push_back(c1);
	col2.push_back(i);
	}
	}
	}
	// Second arg is constant.
	else if(q.SecondElementType.compare("Constant") == 0){
	int c2 = atoi(q.SecondElementName.c_str());
	if(c2>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(q.FirstElementType.compare("Statement") == 0){
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(i).at(c2) == 1){
	col1.push_back(i);
	col2.push_back(c2);
	}
	}
	else{
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
	col1.push_back(i);
	col2.push_back(c2);
	}
	}
	}
	// Both arg are not constant.
	else{
	// Both arg are of statement type.
	if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
	if(	q.FirstElementName.compare("_") == 0 && q.SecondElementName.compare("_") == 0 || 
	q.FirstElementName.compare(q.SecondElementName) != 0	)
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// First arg is of statement type.
	else if(q.FirstElementType.compare("Statement") == 0){
	for(int i=0;i<list.size();i++)
	if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// Second arg is of statemnt type.
	else if(q.SecondElementType.compare("Statement") == 0){
	for(int i=0;i<list.size();i++)
	if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// Both args are not of the type statement.
	else{
	if(q.FirstElementName.compare(q.SecondElementName) != 0)
	for(int i=0;i<list.size();i++)
	if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
	q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	*/
	queryTree.push_back(qtNode);
}

void QueryProcessor::preQueryParent(funcQuery_t q, int po){
	queryTreeNode_t qtNode;
	qtNode.type = "Parent";
	qtNode.numOfColumn = 2;
	qtNode.position=po;
	qtNode.colName.push_back(q.FirstElementName);
	qtNode.colName.push_back(q.SecondElementName);
	/*
	vector<int> col1, col2;

	int totalLineNum = (*pkb).getTotalLineNum();
	vector<pair<int,int>> list = (*pkb).getParentList();
	vector<vector<int>> matrix = (*pkb).getParentMatrix();

	AST ast = (*pkb).getAST();

	// Both args are constant.
	if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
	if(c1>totalLineNum || c2>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(matrix.at(c1).at(c2) == 1){
	col1.push_back(c1);
	col2.push_back(c2);	
	}
	}
	// First arg is constant.
	else if(q.FirstElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str());
	if(c1>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(q.SecondElementType.compare("Statement") == 0){
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(c1).at(i) == 1){
	col1.push_back(c1);
	col2.push_back(i);
	}
	}
	else{
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
	col1.push_back(c1);
	col2.push_back(i);
	}
	}
	}
	// Second arg is constant.
	else if(q.SecondElementType.compare("Constant") == 0){
	int c2 = atoi(q.SecondElementName.c_str());
	if(c2>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(q.FirstElementType.compare("Statement") == 0){
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(i).at(c2) == 1){
	col1.push_back(i);
	col2.push_back(c2);
	}
	}
	else{
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
	col1.push_back(i);
	col2.push_back(c2);
	}
	}
	}
	// Both arg are not constant.
	else{
	// Both arg are of statement type.
	if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
	if(	q.FirstElementName.compare("_") == 0 && q.SecondElementName.compare("_") == 0 || 
	q.FirstElementName.compare(q.SecondElementName) != 0	)
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// First arg is of statement type.
	else if(q.FirstElementType.compare("Statement") == 0){
	for(int i=0;i<list.size();i++)
	if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// Second arg is of statemnt type.
	else if(q.SecondElementType.compare("Statement") == 0){
	for(int i=0;i<list.size();i++)
	if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// Both args are not of the type statement.
	else{
	if(q.FirstElementName.compare(q.SecondElementName) != 0)
	for(int i=0;i<list.size();i++)
	if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
	q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	*/
	queryTree.push_back(qtNode);
}

void QueryProcessor::preQueryParentStar(funcQuery_t q, int po){
	queryTreeNode_t qtNode;
	qtNode.type = "Parent*";
	qtNode.numOfColumn = 2;
	qtNode.position=po;
	qtNode.colName.push_back(q.FirstElementName);
	qtNode.colName.push_back(q.SecondElementName);
	/*
	vector<int> col1, col2;

	int totalLineNum = (*pkb).getTotalLineNum();
	vector<pair<int,int>> list = (*pkb).getParentStarList();
	vector<vector<int>> matrix = (*pkb).getParentStarMatrix();

	AST ast = (*pkb).getAST();

	// Both args are constant.
	if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
	if(c1>totalLineNum || c2>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(matrix.at(c1).at(c2) == 1){
	col1.push_back(c1);
	col2.push_back(c2);	
	}
	}
	// First arg is constant.
	else if(q.FirstElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str());
	if(c1>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(q.SecondElementType.compare("Statement") == 0){
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(c1).at(i) == 1){
	col1.push_back(c1);
	col2.push_back(i);
	}
	}
	else{
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
	col1.push_back(c1);
	col2.push_back(i);
	}
	}
	}
	// Second arg is constant.
	else if(q.SecondElementType.compare("Constant") == 0){
	int c2 = atoi(q.SecondElementName.c_str());
	if(c2>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(q.FirstElementType.compare("Statement") == 0){
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(i).at(c2) == 1){
	col1.push_back(i);
	col2.push_back(c2);
	}
	}
	else{
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
	col1.push_back(i);
	col2.push_back(c2);
	}
	}
	}
	// Both arg are not constant.
	else{
	// Both arg are of statement type.
	if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
	if(	q.FirstElementName.compare("_") == 0 && q.SecondElementName.compare("_") == 0 || 
	q.FirstElementName.compare(q.SecondElementName) != 0	)
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// First arg is of statement type.
	else if(q.FirstElementType.compare("Statement") == 0){
	for(int i=0;i<list.size();i++)
	if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// Second arg is of statemnt type.
	else if(q.SecondElementType.compare("Statement") == 0){
	for(int i=0;i<list.size();i++)
	if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// Both args are not of the type statement.
	else{
	if(q.FirstElementName.compare(q.SecondElementName) != 0)
	for(int i=0;i<list.size();i++)
	if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
	q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	*/
	queryTree.push_back(qtNode);
}

void QueryProcessor::preQueryModifies(funcQuery_t q, int po){
	queryTreeNode_t qtNode;
	qtNode.type = "Modifies";
	qtNode.numOfColumn = 2;
	qtNode.position=po;
	
	stringstream temp1, temp2;
	string colName1, colName2;

	if(q.FirstElementType == "String")
		temp1 << q.FirstElementName << "_str";
	else temp1 << q.FirstElementName;
	temp1 >> colName1;
	qtNode.colName.push_back(colName1);

	if(q.SecondElementType == "String")
		temp2 << q.SecondElementName << "_str";
	else temp2 << q.SecondElementName;
	temp2 >> colName2;
	qtNode.colName.push_back(colName2);
	/*
	vector<pair<int,int>> list = (*pkb).getFullModifiesTable();
	vector<pair<int,int>> procModifiesList = (*pkb).getPModifiesTableV2();
	int totalLineNum = (*pkb).getTotalLineNum();
	ProcTable procTable = (*pkb).getProcTable();

	VarTable varTable = (*pkb).getVarTable();
	AST ast = (*pkb).getAST();

	vector<int> col1, col2;
	// First arg is procedure
	if(q.FirstElementType == "Procedure"){
	// Case Modifies(p,v) || Case Modifies(p,_)
	if(q.SecondElementType == "Variable" || q.SecondElementName == "_"){
	for(int i=0;i<procModifiesList.size();i++){
	col1.push_back(procModifiesList.at(i).first);
	col2.push_back(procModifiesList.at(i).second);
	}
	}
	// Case Modifies(p, "x")
	else{
	for(int i=0;i<procModifiesList.size();i++){
	int v2 = varTable.getVarIndex(q.SecondElementName);
	if(procModifiesList.at(i).second == v2){
	col1.push_back(procModifiesList.at(i).first);
	col2.push_back(procModifiesList.at(i).second);
	}
	}
	}
	}
	else if(q.FirstElementType == "String"){
	if(q.SecondElementType == "Variable" || q.SecondElementName == "_"){
	for(int i=0;i<procModifiesList.size();i++){
	int p = procTable.getProIndex(q.FirstElementName);
	if(procModifiesList.at(i).first == p){
	col1.push_back(procModifiesList.at(i).first);
	col2.push_back(procModifiesList.at(i).second);
	}
	}
	}
	else{
	for(int i=0;i<procModifiesList.size();i++){
	int v2 = varTable.getVarIndex(q.SecondElementName);
	int p = procTable.getProIndex(q.FirstElementName);
	if(procModifiesList.at(i).first == p && procModifiesList.at(i).second == v2){
	col1.push_back(procModifiesList.at(i).first);
	col2.push_back(procModifiesList.at(i).second);
	}
	}
	}
	}
	// First arg is constant
	else if(q.FirstElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str());
	if(c1>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	// Case Modifies(1,v)
	if(q.SecondElementType == "Variable"){
	for(int i=0;i<list.size();i++)
	if(list.at(i).first == c1){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	else{
	// Case Modifies(1,_)
	if(q.SecondElementName.compare("_") == 0){
	for(int i=0;i<list.size();i++)
	if(list.at(i).first == c1){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// Case Modifies(1,"x")
	else{
	int v2 = varTable.getVarIndex(q.SecondElementName);
	if(isInList(c1,v2,list)){
	col1.push_back(c1);
	col2.push_back(v2);
	}
	}
	}
	}
	// First arg is not constant.
	else{
	// First arg is statement.
	if(q.FirstElementType.compare("Statement") == 0){
	// Case Modifies(s,v)
	if(q.SecondElementType == "Variable"){
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	else{
	// Case Modifies(s,_)
	if(q.SecondElementName.compare("_") == 0){
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// Case Modifies(s,"x")
	else{
	int v2 = varTable.getVarIndex(q.SecondElementName);
	for(int i=0;i<list.size();i++)
	if(list.at(i).second == v2){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	}
	// First arg is not statement.
	else{
	// Case Modifies(a/w,v)
	if(q.SecondElementType == "Variable"){
	for(int i=0;i<list.size();i++)
	if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0){	
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	else{
	// Case Modifies(a/w,_)
	if(q.SecondElementName.compare("_") == 0){
	for(int i=0;i<list.size();i++)
	if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0){	
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// Case Modifies(a/w,"x")
	else{
	int v2 = varTable.getVarIndex(q.SecondElementName);
	for(int i=0;i<list.size();i++)
	if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0 &&
	list.at(i).second == v2){					
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	}
	}
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	*/
	queryTree.push_back(qtNode);
}

void QueryProcessor::preQueryUses(funcQuery_t q, int po){
	queryTreeNode_t qtNode;
	qtNode.type = "Uses";
	qtNode.numOfColumn = 2;
	qtNode.position=po;

	stringstream temp1, temp2;
	string colName1, colName2;

	if(q.FirstElementType == "String")
		temp1 << q.FirstElementName << "_str";
	else temp1 << q.FirstElementName;
	temp1 >> colName1;
	qtNode.colName.push_back(colName1);

	if(q.SecondElementType == "String")
		temp2 << q.SecondElementName << "_str";
	else temp2 << q.SecondElementName;
	temp2 >> colName2;
	qtNode.colName.push_back(colName2);
	/*
	vector<pair<int,int>> list = (*pkb).getFullUsesTable();
	vector<pair<int,int>> procUsesList = (*pkb).getPUsesTableV2();
	int totalLineNum = (*pkb).getTotalLineNum();

	ProcTable procTable = (*pkb).getProcTable();
	VarTable varTable = (*pkb).getVarTable();
	AST ast = (*pkb).getAST();

	vector<int> col1, col2;
	// First arg is procedure
	if(q.FirstElementType == "Procedure"){
	// Case Uses(p,v) || Case Uses(p,_)
	if(q.SecondElementType == "Variable" || q.SecondElementName == "_"){
	for(int i=0;i<procUsesList.size();i++){
	col1.push_back(procUsesList.at(i).first);
	col2.push_back(procUsesList.at(i).second);
	}
	}
	// Case Uses(p, "x")
	else{
	for(int i=0;i<procUsesList.size();i++){
	int v2 = varTable.getVarIndex(q.SecondElementName);
	if(procUsesList.at(i).second == v2){
	col1.push_back(procUsesList.at(i).first);
	col2.push_back(procUsesList.at(i).second);
	}
	}
	}
	}
	else if(q.FirstElementType == "String"){
	if(q.SecondElementType == "Variable" || q.SecondElementName == "_"){
	for(int i=0;i<procUsesList.size();i++){
	int p = procTable.getProIndex(q.FirstElementName);
	if(procUsesList.at(i).first == p){
	col1.push_back(procUsesList.at(i).first);
	col2.push_back(procUsesList.at(i).second);
	}
	}
	}
	else{
	for(int i=0;i<procUsesList.size();i++){
	int v2 = varTable.getVarIndex(q.SecondElementName);
	int p = procTable.getProIndex(q.FirstElementName);
	if(procUsesList.at(i).first == p && procUsesList.at(i).second == v2){
	col1.push_back(procUsesList.at(i).first);
	col2.push_back(procUsesList.at(i).second);
	}
	}
	}
	}
	// First arg is constant
	else if(q.FirstElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str());
	if(c1>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	// Case Uses(1,v)
	if(q.SecondElementType == "Variable"){
	for(int i=0;i<list.size();i++)
	if(list.at(i).first == c1){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	else{
	// Case Uses(1,_)
	if(q.SecondElementName.compare("_") == 0){
	for(int i=0;i<list.size();i++)
	if(list.at(i).first == c1){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// Case Uses(1,"x")
	else{
	int c2 = varTable.getVarIndex(q.SecondElementName);
	if(isInList(c1,c2,list)){
	col1.push_back(c1);
	col2.push_back(c2);
	}
	}
	}
	}
	// First arg is not constant.
	else{
	// First arg is statement.
	if(q.FirstElementType.compare("Statement") == 0){
	// Case Uses(s,v)
	if(q.SecondElementType == "Variable"){
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	else{
	// Case Uses(s,_)
	if(q.SecondElementName.compare("_") == 0){
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// Case Uses(s,"x")
	else{
	int c2 = varTable.getVarIndex(q.SecondElementName);
	for(int i=0;i<list.size();i++)
	if(list.at(i).second == c2){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	}
	// First arg is not statement.
	else{
	// Case Uses(a/w,v)
	if(q.SecondElementType == "Variable"){
	for(int i=0;i<list.size();i++)
	if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0){	
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	else{
	// Case Uses(a/w,_)
	if(q.SecondElementName.compare("_") == 0){
	for(int i=0;i<list.size();i++)
	if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0){	
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// Case Uses(a/w,"x")
	else{
	int c2 = varTable.getVarIndex(q.SecondElementName);
	for(int i=0;i<list.size();i++)
	if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0 &&
	list.at(i).second == c2){					
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	}
	}
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	*/
	queryTree.push_back(qtNode);
}

void QueryProcessor::preQueryCall(funcQuery_t q, int po){
	queryTreeNode_t qtNode;
	qtNode.type = "Calls";
	qtNode.numOfColumn = 2;
	qtNode.position=po;

	stringstream temp1, temp2;
	string colName1, colName2;

	if(q.FirstElementType == "String")
		temp1 << q.FirstElementName << "_str";
	else temp1 << q.FirstElementName;
	temp1 >> colName1;
	qtNode.colName.push_back(colName1);

	if(q.SecondElementType == "String")
		temp2 << q.SecondElementName << "_str";
	else temp2 << q.SecondElementName;
	temp2 >> colName2;
	qtNode.colName.push_back(colName2);
	/*
	vector<int> col1, col2;

	Calls calls = (*pkb).getCalls();
	vector<pair<int,int>> list = (*pkb).getCallsList();
	ProcTable procTable = (*pkb).getProcTable();

	if(q.FirstElementType == "Procedure" && q.SecondElementType == "Procedure"){
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	else if(q.FirstElementType == "Procedure"){
	if(q.SecondElementName == "_"){
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	else{
	for(int i=0;i<list.size();i++){
	string procName = procTable.getProName(list.at(i).second);
	if(procName == q.SecondElementName){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	}
	else if(q.SecondElementType == "Procedure"){
	if(q.FirstElementName == "_"){
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	else{
	for(int i=0;i<list.size();i++){
	string procName = procTable.getProName(list.at(i).first);
	if(procName == q.FirstElementName){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	}
	else{
	if(q.FirstElementName == "_" && q.SecondElementName == "_"){
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	else if(q.FirstElementName == "_"){
	int proc2Idx = procTable.getProIndex(q.SecondElementName);
	for(int i=0;i<list.size();i++){
	if(list.at(i).second == proc2Idx){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	else if(q.SecondElementName == "_"){
	int proc1Idx = procTable.getProIndex(q.FirstElementName);
	for(int i=0;i<list.size();i++){
	if(list.at(i).first == proc1Idx){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	else{
	int procNum1 = procTable.getProIndex(q.FirstElementName), procNum2 = procTable.getProIndex(q.SecondElementName);
	if(calls.isCall(procNum1, procNum2)){
	col1.push_back(procNum1);
	col2.push_back(procNum2);
	}
	}
	}

	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	*/
	queryTree.push_back(qtNode);
}

void QueryProcessor::preQueryCallStar(funcQuery_t q, int po){
	queryTreeNode_t qtNode;
	qtNode.type = "Calls*";
	qtNode.numOfColumn = 2;
	qtNode.position=po;

	stringstream temp1, temp2;
	string colName1, colName2;

	if(q.FirstElementType == "String")
		temp1 << q.FirstElementName << "_str";
	else temp1 << q.FirstElementName;
	temp1 >> colName1;
	qtNode.colName.push_back(colName1);

	if(q.SecondElementType == "String")
		temp2 << q.SecondElementName << "_str";
	else temp2 << q.SecondElementName;
	temp2 >> colName2;
	qtNode.colName.push_back(colName2);
	/*
	vector<int> col1, col2;

	Calls calls = (*pkb).getCalls();
	vector<pair<int,int>> list = (*pkb).getCallsStarList();
	ProcTable procTable = (*pkb).getProcTable();

	if(q.FirstElementType == "Procedure" && q.SecondElementType == "Procedure"){
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	else if(q.FirstElementType == "Procedure"){
	if(q.SecondElementName == "_"){
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	else{
	for(int i=0;i<list.size();i++){
	string procName = procTable.getProName(list.at(i).second);
	if(procName == q.SecondElementName){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	}
	else if(q.SecondElementType == "Procedure"){
	if(q.FirstElementName == "_"){
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	else{
	for(int i=0;i<list.size();i++){
	string procName = procTable.getProName(list.at(i).first);
	if(procName == q.FirstElementName){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	}
	else{
	if(q.FirstElementName == "_" && q.SecondElementName == "_"){
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	else if(q.FirstElementName == "_"){
	int proc2Idx = procTable.getProIndex(q.SecondElementName);
	for(int i=0;i<list.size();i++){
	if(list.at(i).second == proc2Idx){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	else if(q.SecondElementName == "_"){
	int proc1Idx = procTable.getProIndex(q.FirstElementName);
	for(int i=0;i<list.size();i++){
	if(list.at(i).first == proc1Idx){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	else{
	int procNum1 = procTable.getProIndex(q.FirstElementName), procNum2 = procTable.getProIndex(q.SecondElementName);
	if(calls.isCall(procNum1, procNum2)){
	col1.push_back(procNum1);
	col2.push_back(procNum2);
	}
	}
	}

	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	*/
	queryTree.push_back(qtNode);
}

void QueryProcessor::preQueryNext(funcQuery_t q, int po){
	queryTreeNode_t qtNode;
	qtNode.type = "Next";
	qtNode.numOfColumn = 2;
	qtNode.position=po;
	qtNode.colName.push_back(q.FirstElementName);
	qtNode.colName.push_back(q.SecondElementName);
	/*
	vector<int> col1, col2;

	int totalLineNum = (*pkb).getTotalLineNum();
	vector<pair<int,int>> list = (*pkb).getNextList();
	vector<vector<int>> matrix = (*pkb).getNextMatrix();

	AST ast = (*pkb).getAST();

	// Both args are constant.
	if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
	if(c1>totalLineNum || c2>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(matrix.at(c1).at(c2) == 1){
	col1.push_back(c1);
	col2.push_back(c2);	
	}
	}
	// First arg is constant.
	else if(q.FirstElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str());
	if(c1>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(q.SecondElementType.compare("Statement") == 0){
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(c1).at(i) == 1){
	col1.push_back(c1);
	col2.push_back(i);
	}
	}
	else{
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
	col1.push_back(c1);
	col2.push_back(i);
	}
	}
	}
	// Second arg is constant.
	else if(q.SecondElementType.compare("Constant") == 0){
	int c2 = atoi(q.SecondElementName.c_str());
	if(c2>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(q.FirstElementType.compare("Statement") == 0){
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(i).at(c2) == 1){
	col1.push_back(i);
	col2.push_back(c2);
	}
	}
	else{
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
	col1.push_back(i);
	col2.push_back(c2);
	}
	}
	}
	// Both arg are not constant.
	else{
	// Both arg are of statement type.
	if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
	if(q.FirstElementName == q.SecondElementName){
	for(int i=0;i<list.size();i++){
	if(list.at(i).first == list.at(i).second){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	else{
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	// First arg is of statement type.
	else if(q.FirstElementType.compare("Statement") == 0){
	for(int i=0;i<list.size();i++)
	if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// Second arg is of statemnt type.
	else if(q.SecondElementType.compare("Statement") == 0){
	for(int i=0;i<list.size();i++)
	if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// Both args are not of the type statement.
	else{
	if(q.FirstElementName == q.SecondElementName){
	for(int i=0;i<list.size();i++)
	if(	list.at(i).first == list.at(i).second &&
	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
	q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	else{
	for(int i=0;i<list.size();i++)
	if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
	q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	}
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	*/
	queryTree.push_back(qtNode);
}

void QueryProcessor::computeNextStar(){
	StmtTable st = (*pkb).getStmtTable();
	int totalLineNum = (*pkb).getTotalLineNum();

	vector<vector<int>> nextStarMatrix(totalLineNum+1, vector<int>(totalLineNum+1, 0));
	vector<pair<int, int>> nextStarList;

	vector<while_t> wTable = st.getWhileTable();
	vector<if_t> iTable = st.getIfTable();

	for(int i=1;i<=totalLineNum;i++)
		for(int j=1;j<=totalLineNum;j++)
			if(st.getLineDetails(i).procNum == st.getLineDetails(j).procNum && i<j) 
				nextStarMatrix.at(i).at(j) = 1;
	for(int k=0;k<iTable.size();k++)
		for(int i=iTable.at(k).thenStartLine;i<=iTable.at(k).thenEndLine;i++)
			for(int j=iTable.at(k).elseStartLine;j<=iTable.at(k).elseEndLine;j++)
				nextStarMatrix.at(i).at(j) = 0;
	for(int k=0;k<wTable.size();k++)
		for(int i=wTable.at(k).lineNum;i<=wTable.at(k).loopEndLine;i++)
			for(int j=wTable.at(k).lineNum;j<=wTable.at(k).loopEndLine;j++)
				nextStarMatrix.at(i).at(j) = 1;

	for(int i=1;i<=totalLineNum;i++)
		for(int j=1;j<=totalLineNum;j++)
			if(nextStarMatrix.at(i).at(j) == 1)
				nextStarList.push_back(pair<int, int>(i, j));

	(*pkb).setNextStarList(nextStarList);
	(*pkb).setNextStarMatrix(nextStarMatrix);
}
void QueryProcessor::preQueryNextStar(funcQuery_t q, int po){
	queryTreeNode_t qtNode;
	qtNode.type = "Next*";
	qtNode.numOfColumn = 2;
	qtNode.position=po;
	qtNode.colName.push_back(q.FirstElementName);
	qtNode.colName.push_back(q.SecondElementName);
	/*
	vector<int> col1, col2;

	int totalLineNum = (*pkb).getTotalLineNum();
	vector<pair<int,int>> list = nextStarList;
	vector<vector<int>> matrix = nextStarMatrix;

	AST ast = (*pkb).getAST();

	// Both args are constant.
	if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
	if(c1>totalLineNum || c2>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(matrix.at(c1).at(c2) == 1){
	col1.push_back(c1);
	col2.push_back(c2);	
	}
	}
	// First arg is constant.
	else if(q.FirstElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str());
	if(c1>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(q.SecondElementType.compare("Statement") == 0){
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(c1).at(i) == 1){
	col1.push_back(c1);
	col2.push_back(i);
	}
	}
	else{
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
	col1.push_back(c1);
	col2.push_back(i);
	}
	}
	}
	// Second arg is constant.
	else if(q.SecondElementType.compare("Constant") == 0){
	int c2 = atoi(q.SecondElementName.c_str());
	if(c2>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(q.FirstElementType.compare("Statement") == 0){
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(i).at(c2) == 1){
	col1.push_back(i);
	col2.push_back(c2);
	}
	}
	else{
	for(int i=1;i<=totalLineNum;i++)
	if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
	col1.push_back(i);
	col2.push_back(c2);
	}
	}
	}
	// Both arg are not constant.
	else{
	// Both arg are of statement type.
	if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
	if(q.FirstElementName == q.SecondElementName){
	for(int i=0;i<list.size();i++){
	if(list.at(i).first == list.at(i).second){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	else{
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	// First arg is of statement type.
	else if(q.FirstElementType.compare("Statement") == 0){
	for(int i=0;i<list.size();i++)
	if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// Second arg is of statemnt type.
	else if(q.SecondElementType.compare("Statement") == 0){
	for(int i=0;i<list.size();i++)
	if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	// Both args are not of the type statement.
	else{
	if(q.FirstElementName == q.SecondElementName){
	for(int i=0;i<list.size();i++)
	if(	list.at(i).first == list.at(i).second &&
	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
	q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	else{
	for(int i=0;i<list.size();i++)
	if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
	q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	}
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	*/
	queryTree.push_back(qtNode);
}


void QueryProcessor::preQueryNextBip(funcQuery_t q, int po){
	queryTreeNode_t qtNode;
	qtNode.type = "NextBip";
	qtNode.numOfColumn = 2;
	qtNode.position=po;
	qtNode.colName.push_back(q.FirstElementName);
	qtNode.colName.push_back(q.SecondElementName);
	queryTree.push_back(qtNode);
}

void QueryProcessor::computeNextBipStar(){
	vector<vector<int>> BipSeq = (*pkb).getExtendProcedure();
	vector<int> curProcCalls, nextProcCalls;
	Calls calls = (*pkb).getCalls();
	StmtTable st = (*pkb).getStmtTable();
	ProcTable pt = (*pkb).getProcTable();
	int totalLineNum = (*pkb).getTotalLineNum();

	vector<vector<int>> nextBipStarMatrix((*pkb).getNextStarMatrix());
	vector<pair<int,int>> nextBipStarList((*pkb).getNextStarList());

	for(int n=0;n<BipSeq.size();n++){
		int curProc = st.getLineDetails(BipSeq.at(n).at(0)).procNum;
		vector<int> callLines = calls.getLineNum(curProc);
		curProcCalls.insert(curProcCalls.end(), callLines.begin(), callLines.end());

		while(!curProcCalls.empty()){
			for(int i=0;i<curProcCalls.size();i++){
				int line = curProcCalls.at(i), proc = calls.getCalleeFromLineNum(line);
				int procStart = pt.getProStartLine(proc), procEnd = pt.getProcEndLine(proc);

				// Lines can reach this call
				for(int j=1;j<=totalLineNum;j++){
					if(nextBipStarMatrix.at(j).at(line) == 1){
						for(int k=procStart;k<=procEnd;k++){
							if(nextBipStarMatrix.at(j).at(k) == 0)
								nextBipStarList.push_back(pair<int,int>(j,k));
							nextBipStarMatrix.at(j).at(k) = 1;
						}
					}
				}
			}
			for(int i=0;i<curProcCalls.size();i++){
				int line = curProcCalls.at(i), proc = calls.getCalleeFromLineNum(line);
				int procStart = pt.getProStartLine(proc), procEnd = pt.getProcEndLine(proc);

				// Lines this call can reach
				for(int j=1;j<=totalLineNum;j++){
					if(nextBipStarMatrix.at(line).at(j) == 1){
						for(int k=procStart;k<=procEnd;k++){
							if(nextBipStarMatrix.at(k).at(j) == 0)
								nextBipStarList.push_back(pair<int,int>(k,j));
							nextBipStarMatrix.at(k).at(j) = 1;
						}
					}
				}

				// this call can reach lines in called procedure
				for(int k=procStart;k<=procEnd;k++){
					if(nextBipStarMatrix.at(line).at(k) == 0)
						nextBipStarList.push_back(pair<int,int>(line,k));
					nextBipStarMatrix.at(line).at(k) = 1;
				}

				// Prepare call in next level
				vector<int> callLinesInCallee = calls.getLineNum(proc);
				nextProcCalls.insert(nextProcCalls.end(), callLinesInCallee.begin(), callLinesInCallee.end());
			}
			curProcCalls.clear();
			curProcCalls = vector<int>(nextProcCalls);
			nextProcCalls.clear();
		}
	}
	(*pkb).setNextBipStarMatrix(nextBipStarMatrix);
	(*pkb).setNextBipStarList(nextBipStarList);
}
void QueryProcessor::preQueryNextBipStar(funcQuery_t q, int po){
	queryTreeNode_t qtNode;
	qtNode.type = "NextBip*";
	qtNode.numOfColumn = 2;
	qtNode.position=po;
	qtNode.colName.push_back(q.FirstElementName);
	qtNode.colName.push_back(q.SecondElementName);
	queryTree.push_back(qtNode);
}

void QueryProcessor::computeAffects(){
	Affects af = Affects(pkb);
	(*pkb).setAffectsMatrix(af.ComputeAffects());
	(*pkb).setAffectsList(af.GetAffectsList());
}
void QueryProcessor::preQueryAffects(funcQuery_t q, int po){
	queryTreeNode_t qtNode;
	qtNode.type = "Affects";
	qtNode.numOfColumn = 2;
	qtNode.position=po;
	qtNode.colName.push_back(q.FirstElementName);
	qtNode.colName.push_back(q.SecondElementName);
	/*
	vector<int> col1, col2;

	int totalLineNum = (*pkb).getTotalLineNum();
	StmtTable st = (*pkb).getStmtTable();

	vector<pair<int,int>> list = (*pkb).getAffectsList();
	vector<vector<int>> matrix = (*pkb).getAffectsMatrix();

	// Both args are constant.
	if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
	if(c1>totalLineNum || c2>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(st.getLineDetails(c1).type != "Assign" || st.getLineDetails(c2).type != "Assign"){
	throw exception("Affects need query on Assignments.");
	return;
	}
	if(matrix.at(c1).at(c2) == 1){
	col1.push_back(c1);
	col2.push_back(c2);	
	}
	}
	// First arg is constant.
	else if(q.FirstElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str());
	if(c1>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(st.getLineDetails(c1).type != "Assign"){
	throw exception("Affects need query on Assignments.");
	return;
	}
	for(int i=1;i<=totalLineNum;i++){
	if(matrix.at(c1).at(i) == 1){
	col1.push_back(c1);
	col2.push_back(i);
	}
	}
	}
	// Second arg is constant.
	else if(q.SecondElementType.compare("Constant") == 0){
	int c2 = atoi(q.SecondElementName.c_str());
	if(c2>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(st.getLineDetails(c2).type != "Assign"){
	throw exception("Affects need query on Assignments.");
	return;
	}
	for(int i=1;i<=totalLineNum;i++){
	if(matrix.at(i).at(c2) == 1){
	col1.push_back(i);
	col2.push_back(c2);
	}
	}
	}
	// Both arg are not constant.
	else{
	if(q.FirstElementName == q.SecondElementName){
	for(int i=0;i<list.size();i++){
	if(list.at(i).first == list.at(i).second){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	else{
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	*/
	queryTree.push_back(qtNode);
}

void QueryProcessor::computeAffectsStar(){
	int totalLineNum =(*pkb).getTotalLineNum();

	vector<vector<int>> affectsStarMatrix((*pkb).getAffectsMatrix());
	vector<pair<int,int>> affectsStarList((*pkb).getAffectsList());
	StmtTable stmtTable = (*pkb).getStmtTable();

	for(int i=1;i<=totalLineNum;i++){
		for(int j=1;j<=totalLineNum;j++)
			if(affectsStarMatrix.at(i).at(j) == 0 && stmtTable.getLineDetails(i).procNum == stmtTable.getLineDetails(j).procNum){
				for(int k=1;k<=totalLineNum;k++)
					if(affectsStarMatrix.at(i).at(k) == 1 && affectsStarMatrix.at(k).at(j) == 1){
						if(affectsStarMatrix.at(i).at(j) == 0)
							affectsStarList.push_back(pair<int,int>(i,j));
						affectsStarMatrix.at(i).at(j) = 1;
					}
			}
	}

	for(int i=1;i<=totalLineNum;i++){
		if(affectsStarMatrix.at(i).at(i) == 0)
			for(int k=0;k<=totalLineNum;k++)
				if(affectsStarMatrix.at(i).at(k) == 1 && affectsStarMatrix.at(k).at(i) == 1){
					if(affectsStarMatrix.at(i).at(i) == 0)	
						affectsStarList.push_back(pair<int,int>(i,i));
					affectsStarMatrix.at(i).at(i) = 1;
				}
	}
	(*pkb).setAffectsStarList(affectsStarList);
	(*pkb).setAffectsStarMatrix(affectsStarMatrix);
}
void QueryProcessor::preQueryAffectsStar(funcQuery_t q, int po){
	queryTreeNode_t qtNode;
	qtNode.type = "Affects*";
	qtNode.numOfColumn = 2;
	qtNode.position=po;
	qtNode.colName.push_back(q.FirstElementName);
	qtNode.colName.push_back(q.SecondElementName);
	/*
	vector<int> col1, col2;

	int totalLineNum = (*pkb).getTotalLineNum();
	StmtTable st = (*pkb).getStmtTable();

	vector<pair<int,int>> list = (*pkb).getAffectsStarList();
	vector<vector<int>> matrix = (*pkb).getAffectsStarMatrix();

	// Both args are constant.
	if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
	if(c1>totalLineNum || c2>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(st.getLineDetails(c1).type != "Assign" || st.getLineDetails(c2).type != "Assign"){
	throw exception("Affects need query on Assignments.");
	return;
	}
	if(matrix.at(c1).at(c2) == 1){
	col1.push_back(c1);
	col2.push_back(c2);	
	}
	}
	// First arg is constant.
	else if(q.FirstElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str());
	if(c1>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(st.getLineDetails(c1).type != "Assign"){
	throw exception("Affects need query on Assignments.");
	return;
	}
	for(int i=1;i<=totalLineNum;i++){
	if(matrix.at(c1).at(i) == 1){
	col1.push_back(c1);
	col2.push_back(i);
	}
	}
	}
	// Second arg is constant.
	else if(q.SecondElementType.compare("Constant") == 0){
	int c2 = atoi(q.SecondElementName.c_str());
	if(c2>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(st.getLineDetails(c2).type != "Assign"){
	throw exception("Affects need query on Assignments.");
	return;
	}
	for(int i=1;i<=totalLineNum;i++){
	if(matrix.at(i).at(c2) == 1){
	col1.push_back(i);
	col2.push_back(c2);
	}
	}
	}
	// Both arg are not constant.
	else{
	if(q.FirstElementName == q.SecondElementName){
	for(int i=0;i<list.size();i++){
	if(list.at(i).first == list.at(i).second){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	else{
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	*/
	queryTree.push_back(qtNode);
}

void QueryProcessor::preQueryAffectsBip(funcQuery_t q, int po){
	queryTreeNode_t qtNode;
	qtNode.type = "AffectsBip";
	qtNode.numOfColumn = 2;
	qtNode.position=po;
	qtNode.colName.push_back(q.FirstElementName);
	qtNode.colName.push_back(q.SecondElementName);
	/*
	vector<int> col1, col2;

	int totalLineNum = (*pkb).getTotalLineNum();
	StmtTable st = (*pkb).getStmtTable();

	vector<vector<int>> matrix = affectsBip.GetAffectsBipMatrix();
	vector<pair<int,int>> list = affectsBip.GetAffectsBipList();

	// Both args are constant.
	if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
	if(c1>totalLineNum || c2>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(st.getLineDetails(c1).type != "Assign" || st.getLineDetails(c2).type != "Assign"){
	throw exception("Affects need query on Assignments.");
	return;
	}
	if(matrix.at(c1).at(c2) == 1){
	col1.push_back(c1);
	col2.push_back(c2);	
	}
	}
	// First arg is constant.
	else if(q.FirstElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str());
	if(c1>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(st.getLineDetails(c1).type != "Assign"){
	throw exception("Affects need query on Assignments.");
	return;
	}
	for(int i=1;i<=totalLineNum;i++){
	if(matrix.at(c1).at(i) == 1){
	col1.push_back(c1);
	col2.push_back(i);
	}
	}
	}
	// Second arg is constant.
	else if(q.SecondElementType.compare("Constant") == 0){
	int c2 = atoi(q.SecondElementName.c_str());
	if(c2>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(st.getLineDetails(c2).type != "Assign"){
	throw exception("Affects need query on Assignments.");
	return;
	}
	for(int i=1;i<=totalLineNum;i++){
	if(matrix.at(i).at(c2) == 1){
	col1.push_back(i);
	col2.push_back(c2);
	}
	}
	}
	// Both arg are not constant.
	else{
	if(q.FirstElementName == q.SecondElementName){
	for(int i=0;i<list.size();i++){
	if(list.at(i).first == list.at(i).second){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	else{
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	*/
	queryTree.push_back(qtNode);
}

void QueryProcessor::preQueryAffectsBipStar(funcQuery_t q, int po){
	queryTreeNode_t qtNode;
	qtNode.type = "AffectsBip*";
	qtNode.numOfColumn = 2;
	qtNode.position=po;
	qtNode.colName.push_back(q.FirstElementName);
	qtNode.colName.push_back(q.SecondElementName);
	/*
	vector<int> col1, col2;

	int totalLineNum = (*pkb).getTotalLineNum();
	StmtTable st = (*pkb).getStmtTable();

	vector<vector<int>> matrix = affectsBip.GetAffectsBipStarMatrix();
	vector<pair<int,int>> list = affectsBip.GetAffectsBipStarList();

	// Both args are constant.
	if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
	if(c1>totalLineNum || c2>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(st.getLineDetails(c1).type != "Assign" || st.getLineDetails(c2).type != "Assign"){
	throw exception("Affects need query on Assignments.");
	return;
	}
	if(matrix.at(c1).at(c2) == 1){
	col1.push_back(c1);
	col2.push_back(c2);	
	}
	}
	// First arg is constant.
	else if(q.FirstElementType.compare("Constant") == 0){
	int c1 = atoi(q.FirstElementName.c_str());
	if(c1>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(st.getLineDetails(c1).type != "Assign"){
	throw exception("Affects need query on Assignments.");
	return;
	}
	for(int i=1;i<=totalLineNum;i++){
	if(matrix.at(c1).at(i) == 1){
	col1.push_back(c1);
	col2.push_back(i);
	}
	}
	}
	// Second arg is constant.
	else if(q.SecondElementType.compare("Constant") == 0){
	int c2 = atoi(q.SecondElementName.c_str());
	if(c2>totalLineNum){
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	queryTree.push_back(qtNode);
	return;
	}
	if(st.getLineDetails(c2).type != "Assign"){
	throw exception("Affects need query on Assignments.");
	return;
	}
	for(int i=1;i<=totalLineNum;i++){
	if(matrix.at(i).at(c2) == 1){
	col1.push_back(i);
	col2.push_back(c2);
	}
	}
	}
	// Both arg are not constant.
	else{
	if(q.FirstElementName == q.SecondElementName){
	for(int i=0;i<list.size();i++){
	if(list.at(i).first == list.at(i).second){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	else{
	for(int i=0;i<list.size();i++){
	col1.push_back(list.at(i).first);
	col2.push_back(list.at(i).second);
	}
	}
	}
	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	*/
	queryTree.push_back(qtNode);
}

bool QueryProcessor::areIdentical(vector<Pattern_node> t1,int index1, vector<Pattern_node> t2, int index2)
{
	// base cases
	if(	(t1.empty() || t1.size() == 0 || index1<0 || index1>=t1.size()) && 
		(t2.empty() || t2.size() == 0 || index2<0 || index2>=t2.size()) )
		return true;

	if( (t1.empty() || t1.size() == 0 || index1<0 || index1>=t1.size()) || 
		(t2.empty() || t2.size() == 0 || index2<0 || index2>=t2.size()) )
		return false;

	// Check if the data of both roots is same and data of left and right subtrees are also same
	return (t1.at(index1).getData() == t2.at(index2).getData() &&
		areIdentical(t1, t1.at(index1).getLeft(), t2, t2.at(index2).getLeft()) &&
		areIdentical(t1, t1.at(index1).getRight(), t2, t2.at(index2).getRight())	);
}
bool QueryProcessor::isSubtree(vector<Pattern_node> t1, int index1, vector<Pattern_node> t2, int index2){
	/* This function returns true if t1 is a subtree of t2, otherwise false */
	// base cases 
	if (t1.empty() || t1.size() == 0 || index1<0 || index1>=t1.size() )
		return true;

	if (t2.empty() || t2.size() == 0 || index2<0 || index2>=t2.size() )
		return false;

	// Check the tree with root as current node
	if (areIdentical(t1, index1, t2, index2))
		return true;

	// If the tree with root as current node doesn't match then try left and right subtrees one by one
	return isSubtree(t1, 0, t2, t2.at(index2).getLeft()) ||
		isSubtree(t1, 0, t2, t2.at(index2).getRight());
}
void QueryProcessor::preQueryPattern(patternQuery_t q,int po){
	queryTreeNode_t qtNode;
	qtNode.type = "Pattern";
	qtNode.position=po;
	/*
	vector<Pattern> pt = (*pkb).getPatternTable().getPatternTable();
	VarTable varTable = (*pkb).getVarTable();
	*/
	// 1st arg is variable reference
	if(!q.isVarRefVariable){
		qtNode.numOfColumn = 1;
		qtNode.colName.push_back(q.ElementName);
		vector<int> col;
		/*
		// Assign Pattern
		if(q.ElementType == "Assign"){
		// Pattern a (_,*)
		if(q.VarRef == "_"){
		// a(_,_)
		if(q.Expression.empty() || q.Expression.size() == 0){
		for(int i=0;i<pt.size();i++)
		if(pt.at(i).getType() == 0)
		col.push_back(pt.at(i).getLineNum());
		}
		// a(_,exp)
		else if(!q.ExpWithUnderscore){
		for(int i=0;i<pt.size();i++){
		if(pt.at(i).getType() == 0 && areIdentical(q.Expression, 0,pt.at(i).getNodeTree(),0))
		col.push_back(pt.at(i).getLineNum());
		}
		}
		// a(_,_exp_)
		else{
		for(int i=0;i<pt.size();i++){
		if(pt.at(i).getType() == 0 && isSubtree(q.Expression,0, pt.at(i).getNodeTree(),0))
		col.push_back(pt.at(i).getLineNum());
		}
		}
		}
		// Pattern a("",*)
		else{
		// a("",_)
		if(q.Expression.empty() || q.Expression.size() == 0){
		for(int i=0;i<pt.size();i++)
		if(pt.at(i).getType() == 0 && pt.at(i).getVarName() == q.VarRef)
		col.push_back(pt.at(i).getLineNum());
		}
		// a("",exp)
		else if(!q.ExpWithUnderscore){
		for(int i=0;i<pt.size();i++){
		if(pt.at(i).getType() == 0 && q.VarRef == pt.at(i).getVarName() && areIdentical(q.Expression,0, pt.at(i).getNodeTree(),0))
		col.push_back(pt.at(i).getLineNum());
		}
		}
		// a("",_exp_)
		else{
		for(int i=0;i<pt.size();i++){
		if(pt.at(i).getType() == 0 && q.VarRef == pt.at(i).getVarName() && isSubtree(q.Expression, 0,pt.at(i).getNodeTree(),0))
		col.push_back(pt.at(i).getLineNum());
		}
		}
		}
		}
		// Pattern while|if
		else{
		for(int i=0;i<pt.size();i++)
		if(patternType.at(pt.at(i).getType()) == q.ElementType && q.VarRef == pt.at(i).getVarName())
		col.push_back(pt.at(i).getLineNum());
		}

		qtNode.table.push_back(col);
		*/
	}
	// 1st arg not variable reference
	else{
		qtNode.numOfColumn = 2;
		qtNode.colName.push_back(q.ElementName);
		qtNode.colName.push_back(q.VarRef);
		/*
		vector<int> col1, col2;

		// Assign
		if(q.ElementType == "Assign"){
		// Pattern a (v,*)
		// a(v,_)
		if(q.Expression.empty() || q.Expression.size() == 0){
		for(int i=0;i<pt.size();i++)
		if(pt.at(i).getType() == 0){
		col1.push_back(pt.at(i).getLineNum());
		col2.push_back(varTable.getVarIndex(pt.at(i).getVarName()));
		}
		}
		// a(v,exp)
		else if(!q.ExpWithUnderscore){
		for(int i=0;i<pt.size();i++){
		if(pt.at(i).getType() == 0 && areIdentical(q.Expression, 0,pt.at(i).getNodeTree(),0)){
		col1.push_back(pt.at(i).getLineNum());
		col2.push_back(varTable.getVarIndex(pt.at(i).getVarName()));
		}
		}
		}
		// a(v,_exp_)
		else{
		for(int i=0;i<pt.size();i++){
		if(pt.at(i).getType() == 0 && isSubtree(q.Expression,0, pt.at(i).getNodeTree(),0)){
		col1.push_back(pt.at(i).getLineNum());
		col2.push_back(varTable.getVarIndex(pt.at(i).getVarName()));
		}
		}
		}
		}
		// While/If
		else{
		for(int i=0;i<pt.size();i++)
		if(patternType.at(pt.at(i).getType()) == q.ElementType){
		col1.push_back(pt.at(i).getLineNum());
		col2.push_back(varTable.getVarIndex(pt.at(i).getVarName()));
		}
		}
		qtNode.table.push_back(col1);
		qtNode.table.push_back(col2);
		*/
	}

	queryTree.push_back(qtNode);
}


void QueryProcessor::preQueryCompare(compareQuery_t q, int po){
	queryTreeNode_t qtNode;
	qtNode.position=po;
	qtNode.type = "with-cl";
	/*
	AST ast = (*pkb).getAST();
	StmtTable st = (*pkb).getStmtTable();
	ConstTable constTable = (*pkb).getConstTable();
	ProcTable procTable = (*pkb).getProcTable();
	VarTable varTable = (*pkb).getVarTable();
	vector<int> callProc = (*pkb).getCalleeList();
	int totalLineNum = (*pkb).getTotalLineNum();
	*/
	// int compare
	//// assign
	if(q.leftType == "Assign"){
		if(q.rightType == "Assign" || q.rightType == "Statement"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=1;i<=totalLineNum;i++){
			if(st.getLineDetails(i).type == "Assign"){
			col1.push_back(i);
			col2.push_back(i);
			}
			}
			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "Constant"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=0;i<constTable.getSize();i++){
			int n = constTable.getConstant(i);
			if(n<=totalLineNum && st.getLineDetails(n).type == "Assign")
			col1.push_back(n);
			col2.push_back(n);
			}

			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "Integer"){
			qtNode.numOfColumn = 1;
			qtNode.colName.push_back(q.leftName);
			vector<int> col1;
			/*
			int n = atoi(q.rightName.c_str());
			if(n<=totalLineNum && st.getLineDetails(n).type == "Assign"){
			col1.push_back(n);
			}

			qtNode.table.push_back(col1);
			*/
		}
	}
	//////////////////////////////////////
	//// while
	else if(q.leftType == "While"){
		if(q.rightType == "While" || q.rightType == "Statement"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=1;i<=totalLineNum;i++){
			if(st.getLineDetails(i).type == "While"){
			col1.push_back(i);
			col2.push_back(i);
			}
			}
			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "Constant"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=0;i<constTable.getSize();i++){
			int n = constTable.getConstant(i);
			if(n<=totalLineNum && st.getLineDetails(n).type == "While")
			col1.push_back(n);
			col2.push_back(n);
			}

			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "Integer"){
			qtNode.numOfColumn = 1;
			qtNode.colName.push_back(q.leftName);
			vector<int> col1;
			/*
			int n = atoi(q.rightName.c_str());
			if(n<=totalLineNum && st.getLineDetails(n).type == "While"){
			col1.push_back(n);
			}

			qtNode.table.push_back(col1);
			*/
		}
	}
	//////////////////////////////////////
	//// if
	else if(q.leftType == "If"){
		if(q.rightType == "If" || q.rightType == "Statement"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=1;i<=totalLineNum;i++){
			if(st.getLineDetails(i).type == "If"){
			col1.push_back(i);
			col2.push_back(i);
			}
			}
			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "Constant"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=0;i<constTable.getSize();i++){
			int n = constTable.getConstant(i);
			if(n<=totalLineNum && st.getLineDetails(n).type == "If")
			col1.push_back(n);
			col2.push_back(n);
			}

			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "Integer"){
			qtNode.numOfColumn = 1;
			qtNode.colName.push_back(q.leftName);
			vector<int> col1;
			/*
			int n = atoi(q.rightName.c_str());
			if(n<=totalLineNum && st.getLineDetails(n).type == "If"){
			col1.push_back(n);
			}

			qtNode.table.push_back(col1);
			*/
		}
	}
	///////////////////////
	//// Call
	else if(q.leftType == "Call"){
		if(q.rightType == "Call" || q.rightType == "Statement"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=1;i<=totalLineNum;i++){
			if(st.getLineDetails(i).type == "Call"){
			col1.push_back(i);
			col2.push_back(i);
			}
			}
			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "Constant"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=0;i<constTable.getSize();i++){
			int n = constTable.getConstant(i);
			if(n<=totalLineNum && st.getLineDetails(n).type == "Call")
			col1.push_back(n);
			col2.push_back(n);
			}

			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "Integer"){
			qtNode.numOfColumn = 1;
			qtNode.colName.push_back(q.leftName);
			vector<int> col1;
			/*
			int n = atoi(q.rightName.c_str());
			if(n<=totalLineNum && st.getLineDetails(n).type == "Call"){
			col1.push_back(n);
			}

			qtNode.table.push_back(col1);
			*/
		}
	}
	//////////////////////////////////////
	//// stmt
	else if(q.leftType == "Statement"){
		if(q.rightType == "Assign"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=1;i<=totalLineNum;i++){
			if(st.getLineDetails(i).type == "Assign"){
			col1.push_back(i);
			col2.push_back(i);
			}
			}
			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "While"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=1;i<=totalLineNum;i++){
			if(st.getLineDetails(i).type == "While"){
			col1.push_back(i);
			col2.push_back(i);
			}
			}
			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "If"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=1;i<=totalLineNum;i++){
			if(st.getLineDetails(i).type == "If"){
			col1.push_back(i);
			col2.push_back(i);
			}
			}
			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "CallStmt"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=1;i<=totalLineNum;i++){
			if(st.getLineDetails(i).type == "Call"){
			col1.push_back(i);
			col2.push_back(i);
			}
			}
			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "Statement"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=1;i<=totalLineNum;i++){
			col1.push_back(i);
			col2.push_back(i);
			}
			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "Constant"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=0;i<constTable.getSize();i++){
			int n = constTable.getConstant(i);
			if(n<=totalLineNum)
			col1.push_back(n);
			col2.push_back(n);
			}

			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "Integer"){
			qtNode.numOfColumn = 1;
			qtNode.colName.push_back(q.leftName);
			vector<int> col1;
			/*
			int n = atoi(q.rightName.c_str());
			if(n<=totalLineNum)
			col1.push_back(n);

			qtNode.table.push_back(col1);
			*/
		}
	}
	//////////////////////////////////////
	//// const
	else if(q.leftType == "Constant"){
		if(q.rightType == "Assign"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=0;i<constTable.getSize();i++){
			int n = constTable.getConstant(i);
			if(n<=totalLineNum && st.getLineDetails(n).type == "Assign")
			col1.push_back(n);
			col2.push_back(n);
			}

			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "While"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=0;i<constTable.getSize();i++){
			int n = constTable.getConstant(i);
			if(n<=totalLineNum && st.getLineDetails(n).type == "While")
			col1.push_back(n);
			col2.push_back(n);
			}

			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "If"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=0;i<constTable.getSize();i++){
			int n = constTable.getConstant(i);
			if(n<=totalLineNum && st.getLineDetails(n).type == "If")
			col1.push_back(n);
			col2.push_back(n);
			}

			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "CallStmt"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=0;i<constTable.getSize();i++){
			int n = constTable.getConstant(i);
			if(n<=totalLineNum && st.getLineDetails(n).type == "Call")
			col1.push_back(n);
			col2.push_back(n);
			}

			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "Statement"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=0;i<constTable.getSize();i++){
			int n = constTable.getConstant(i);
			if(n<=totalLineNum)
			col1.push_back(n);
			col2.push_back(n);
			}

			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "Constant"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=0;i<constTable.getSize();i++){
			int n = constTable.getConstant(i);
			col1.push_back(n);
			col2.push_back(n);
			}

			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "Integer"){
			qtNode.numOfColumn = 1;
			qtNode.colName.push_back(q.leftName);
			vector<int> col1;
			/*
			int n = atoi(q.rightName.c_str());
			if(constTable.hasCon(n))
			col1.push_back(n);

			qtNode.table.push_back(col1);
			*/
		}
	}
	//////////////////////////////////////
	//// int
	else if(q.leftType == "Integer"){
		int n = atoi(q.leftName.c_str());
		if(q.rightType == "Assign"){
			qtNode.numOfColumn = 1;
			qtNode.colName.push_back(q.rightName);
			vector<int> col1;
			/*
			if(st.getLineDetails(n).type == "Assign")
			col1.push_back(n);

			qtNode.table.push_back(col1);
			*/
		}
		else if(q.rightType == "While"){
			qtNode.numOfColumn = 1;
			qtNode.colName.push_back(q.rightName);
			vector<int> col1;
			/*
			if(st.getLineDetails(n).type == "While")
			col1.push_back(n);

			qtNode.table.push_back(col1);
			*/
		}
		else if(q.rightType == "If"){
			qtNode.numOfColumn = 1;
			qtNode.colName.push_back(q.rightName);
			vector<int> col1;
			/*
			if(st.getLineDetails(n).type == "If")
			col1.push_back(n);

			qtNode.table.push_back(col1);
			*/
		}
		else if(q.rightType == "CallStmt"){
			qtNode.numOfColumn = 1;
			qtNode.colName.push_back(q.rightName);
			vector<int> col1;
			/*
			if(st.getLineDetails(n).type == "Call")
			col1.push_back(n);

			qtNode.table.push_back(col1);
			*/
		}
		else if(q.rightType == "Statement"){

			qtNode.numOfColumn = 1;
			qtNode.colName.push_back(q.rightName);
			vector<int> col1;
			/*
			col1.push_back(n);

			qtNode.table.push_back(col1);
			*/
		}
		else if(q.rightType == "Constant"){

			qtNode.numOfColumn = 1;
			qtNode.colName.push_back(q.rightName);
			vector<int> col1;
			/*
			if(constTable.hasCon(n))
			col1.push_back(n);

			qtNode.table.push_back(col1);
			*/
		}
		else if(q.rightType == "Integer"){
			int i = atoi(q.rightName.c_str());
			if(n == i)
				return;
			else{
				qtNode.numOfColumn = 0;
			}
		}
	}

	// string compare
	/////////////////
	//// Proc
	else if(q.leftType == "Procedure"){
		if(q.rightType == "Procedure"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=0;i<procTable.getSize();i++){
			col1.push_back(i);
			col2.push_back(i);
			}

			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "CallProc"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=0;i<callProc.size();i++){
			col1.push_back(callProc.at(i));
			col2.push_back(callProc.at(i));
			}

			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "Variable"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=0;i<procTable.getSize();i++){
			for(int j=0;j<varTable.getSize();j++){
			if(procTable.getProName(i) == varTable.getVarName(j)){
			col1.push_back(i);
			col2.push_back(j);
			}
			}
			}

			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "String"){
			qtNode.numOfColumn = 1;
			qtNode.colName.push_back(q.leftName);
			vector<int> col1;
			/*
			for(int i=0;i<procTable.getSize();i++){
			if(procTable.getProName(i) == q.rightName){
			col1.push_back(i);
			}
			}

			qtNode.table.push_back(col1);
			*/
		}
	}
	///////////////
	//// callproc
	else if(q.leftType == "CallProc"){
		if(q.rightType == "CallProc"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=0;i<callProc.size();i++){
			col1.push_back(callProc.at(i));
			col2.push_back(callProc.at(i));
			}

			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "Variable"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=0;i<callProc.size();i++){
			for(int j=0;j<varTable.getSize();j++){
			if(procTable.getProName(callProc.at(i)) == varTable.getVarName(j)){
			col1.push_back(callProc.at(i));
			col2.push_back(j);
			}
			}
			}

			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "String"){
			qtNode.numOfColumn = 1;
			qtNode.colName.push_back(q.leftName);
			vector<int> col1;
			/*
			for(int i=0;i<callProc.size();i++){
			if(procTable.getProName(callProc.at(i)) == q.rightName){
			col1.push_back(callProc.at(i));
			}
			}

			qtNode.table.push_back(col1);
			*/
		}
	}
	//////////////
	//// variable
	else if(q.leftType == "Variable"){
		if(q.rightType == "Procedure"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=0;i<procTable.getSize();i++){
			for(int j=0;j<varTable.getSize();j++){
			if(procTable.getProName(i) == varTable.getVarName(j)){
			col1.push_back(i);
			col2.push_back(j);
			}
			}
			}

			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "CallProc"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=0;i<callProc.size();i++){
			for(int j=0;j<varTable.getSize();j++){
			if(procTable.getProName(callProc.at(i)) == varTable.getVarName(j)){
			col1.push_back(callProc.at(i));
			col2.push_back(j);
			}
			}
			}

			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "Variable"){
			qtNode.numOfColumn = 2;
			qtNode.colName.push_back(q.leftName);
			qtNode.colName.push_back(q.rightName);
			vector<int> col1, col2;
			/*
			for(int i=0;i<varTable.getSize();i++){
			col1.push_back(i);
			col2.push_back(i);
			}

			qtNode.table.push_back(col1);
			qtNode.table.push_back(col2);
			*/
		}
		else if(q.rightType == "String"){
			qtNode.numOfColumn = 1;
			qtNode.colName.push_back(q.leftName);
			vector<int> col1;
			/*
			for(int i=0;i<varTable.getSize();i++){
			if(varTable.getVarName(i) == q.rightName){
			col1.push_back(i);
			}
			}

			qtNode.table.push_back(col1);
			*/
		}
	}
	///////////////
	//// string
	else if(q.leftType == "String"){
		if(q.rightType == "Procedure"){
			qtNode.numOfColumn = 1;
			qtNode.colName.push_back(q.rightName);
			vector<int> col1;
			/*
			for(int i=0;i<procTable.getSize();i++){
			if(procTable.getProName(i) == q.leftName){
			col1.push_back(i);
			}
			}

			qtNode.table.push_back(col1);
			*/
		}
		else if(q.rightType == "CallProc"){
			qtNode.numOfColumn = 1;
			qtNode.colName.push_back(q.rightName);
			vector<int> col1;
			/*
			for(int i=0;i<callProc.size();i++){
			if(procTable.getProName(callProc.at(i)) == q.leftName){
			col1.push_back(callProc.at(i));
			}
			}

			qtNode.table.push_back(col1);
			*/
		}
		else if(q.rightType == "Variable"){
			qtNode.numOfColumn = 1;
			qtNode.colName.push_back(q.rightName);
			vector<int> col1;
			/*
			for(int i=0;i<varTable.getSize();i++){
			if(varTable.getVarName(i) == q.leftName){
			col1.push_back(i);
			}
			}

			qtNode.table.push_back(col1);
			*/
		}
		else if(q.rightType == "String"){
			if(q.leftName == q.rightName)
				return;
			else qtNode.numOfColumn = 0;
		}
	}

	queryTree.push_back(qtNode);
}

void QueryProcessor::preBuildCallRelationTable(string c, int po){
	queryTreeNode_t qtNode;
	qtNode.type = "CallRelation";
	qtNode.numOfColumn = 2;
	qtNode.position=po;

	strstream ss;
	ss << c << ".procName";
	string s;
	ss >> s;
	qtNode.colName.push_back(c);
	qtNode.colName.push_back(s);
	/*
	vector<int> col1,col2;

	Calls calls = (*pkb).getCalls();
	vector<Triple> callTable = calls.getCalls();
	for(int i=0;i<callTable.size();i++){
	col1.push_back(callTable.at(i).getFirst());
	col2.push_back(callTable.at(i).getThird());
	}

	qtNode.table.push_back(col1);
	qtNode.table.push_back(col2);
	*/
	queryTree.push_back(qtNode);
}

void QueryProcessor::preQueryContains(funcQuery_t q, int po){
	queryTreeNode_t qtNode;
	qtNode.type = "Contains";
	qtNode.numOfColumn = 2;
	qtNode.colName.push_back(q.FirstElementName);
	qtNode.colName.push_back(q.SecondElementName);
	qtNode.position = po;
	
	queryTree.push_back(qtNode);
}

void QueryProcessor::preQueryContainsStar(funcQuery_t q, int po){
	queryTreeNode_t qtNode;
	qtNode.type = "Contains*";
	qtNode.numOfColumn = 2;
	qtNode.colName.push_back(q.FirstElementName);
	qtNode.colName.push_back(q.SecondElementName);
	qtNode.position = po;
	
	queryTree.push_back(qtNode);
}



void QueryProcessor::buildTable(int index, queryTreeNode_t finalTable){
	queryTreeNode_t q = queryTree.at(index);
	if(q.type == "Select")
		BuildSelect(queries.selectQuery, index, finalTable);
	else if(q.type == "Follows")
		QueryFollows(queries.funcQueries.at(q.position), index, finalTable);
	else if(q.type == "Follows*")
		QueryFollowsStar(queries.funcQueries.at(q.position), index, finalTable);
	else if(q.type == "Parent")
		QueryParent(queries.funcQueries.at(q.position), index, finalTable);
	else if(q.type == "Parent*")
		QueryParentStar(queries.funcQueries.at(q.position), index, finalTable);
	else if(q.type == "Modifies")
		QueryModifies(queries.funcQueries.at(q.position), index, finalTable);
	else if(q.type == "Uses")
		QueryUses(queries.funcQueries.at(q.position), index, finalTable);
	else if(q.type == "Calls")
		QueryCall(queries.funcQueries.at(q.position), index, finalTable);
	else if(q.type == "Calls*")
		QueryCallStar(queries.funcQueries.at(q.position), index, finalTable);
	else if(q.type == "Next")
		QueryNext(queries.funcQueries.at(q.position), index, finalTable);
	else if(q.type == "Next*")
		QueryNextStar(queries.funcQueries.at(q.position), index, finalTable);
	else if(q.type == "NextBip")
		QueryNextBip(queries.funcQueries.at(q.position), index, finalTable);
	else if(q.type == "NextBip*")
		QueryNextBipStar(queries.funcQueries.at(q.position), index, finalTable);
	else if(q.type == "Affects")
		QueryAffects(queries.funcQueries.at(q.position), index, finalTable);
	else if(q.type == "Affects*")
		QueryAffectsStar(queries.funcQueries.at(q.position), index, finalTable);
	else if(q.type == "AffectsBip")
		QueryAffectsBip(queries.funcQueries.at(q.position), index, finalTable);
	else if(q.type == "AffectsBip*")
		QueryAffectsBipStar(queries.funcQueries.at(q.position), index, finalTable);
	else if(q.type == "Pattern")
		QueryPattern(queries.patternQueries.at(q.position), index, finalTable);
	else if(q.type == "with-cl")
		QueryCompare(queries.compareQueries.at(q.position), index);
	else if(q.type == "CallRelation")
		BuildCallRelationTable(queries.callRelation.at(q.position), index);
	else if(q.type == "Contains")
		QueryContains(queries.funcQueries.at(q.position), index);
	else if(q.type == "Contains*")
		QueryContainsStar(queries.funcQueries.at(q.position), index);
}

void QueryProcessor::BuildSelect(selectQuery_t q, int index, queryTreeNode_t finalTable){
	AST ast = (*pkb).getAST();
	StmtTable st = (*pkb).getStmtTable();
	VarTable varTable = (*pkb).getVarTable();
	ProcTable procTable = (*pkb).getProcTable();
	ConstTable contTable = (*pkb).getConstTable();
	vector<int> callProc = (*pkb).getCalleeList();


	vector<string>::iterator it = find(finalTable.colName.begin(), finalTable.colName.end(), q.SelectName);
	bool isInList = it != finalTable.colName.end();
	
	string SelectType;
	if(queryTree.at(index).position == -1)
		SelectType = q.SelectType;
	else SelectType = q.tupleType.at(queryTree.at(index).position);

	vector<int>  col1;
	if(isInList){
		int pos = it - finalTable.colName.begin();
		col1 = finalTable.table.at(pos);
	}
	else{
		if(SelectType == "Procedure"){
			for(int i=0;i<procTable.getSize();i++)
				col1.push_back(i);
		}
		else if(SelectType == "CallProc"){
			for(int i=0;i<callProc.size();i++)
				col1.push_back(callProc.at(i));
		}
		else if(SelectType == "Constant"){
			for(int i=0;i<contTable.getSize();i++)
				col1.push_back(contTable.getConstant(i));
		}
		else if(SelectType == "Variable"){
			for(int i=0;i<varTable.getSize();i++)
				col1.push_back(i);
		}
		else if(SelectType == "StmtLst"){
			StmtLstTable slt = (*pkb).getStmtLstTable();
			for(int i=0;i<slt.getSize();i++)
				col1.push_back(slt.getStartLine(i));
		}
		else if(SelectType == "+"){
			PlusTable pt = (*pkb).getPlusTable();
			for(int i=0;i<pt.getSize();i++)
				col1.push_back(pt.getPlus(i));
		}
		else if(SelectType == "-"){
			MinusTable mt = (*pkb).getMinusTable();
			for(int i=0;i<mt.getSize();i++)
				col1.push_back(mt.getMinus(i));
		}
		else if(SelectType == "*"){
			TimesTable tt = (*pkb).getTimesTable();
			for(int i=0;i<tt.getSize();i++)
				col1.push_back(tt.getTimes(i));
		}
		else  if(SelectType == "Statement"){
			for(int i=1;i<=ast.getTotalLineNum();i++)
				col1.push_back(i);
		}
		else{
			for(int i=1;i<=ast.getTotalLineNum();i++)
				if(SelectType == st.getLineDetails(i).type)
					col1.push_back(i);
		}
	}
	queryTree.at(index).table.push_back(col1);
}

void QueryProcessor::QueryFollows(funcQuery_t q, int index, queryTreeNode_t finalTable){
	vector<int> col1, col2, tcol1, tcol2;

	int totalLineNum = (*pkb).getTotalLineNum();
	vector<pair<int,int>> list = (*pkb).getFollowsList();
	vector<vector<int>> matrix = (*pkb).getFollowsMatrix();

	AST ast = (*pkb).getAST();

	int colCase = 0;
	vector<string>::iterator it1 = find(finalTable.colName.begin(), finalTable.colName.end(), q.FirstElementName), 
		it2 = find(finalTable.colName.begin(), finalTable.colName.end(), q.SecondElementName);

	if(  it1 != finalTable.colName.end() ){
		colCase+=1;
		int pos = it1 - finalTable.colName.begin();
		tcol1 = finalTable.table.at(pos);
	}
	if(  it2 != finalTable.colName.end() ){
		colCase+=2;
		int pos = it2 - finalTable.colName.begin();
		tcol2 = finalTable.table.at(pos);
	}

	switch(colCase){
	case 0:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				col1.push_back(c1);
				col2.push_back(c2);	
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						col1.push_back(c1);
						col2.push_back(i);
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						col1.push_back(c1);
						col2.push_back(i);
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						col1.push_back(i);
						col2.push_back(c2);
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						col1.push_back(i);
						col2.push_back(c2);
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(	q.FirstElementName.compare("_") == 0 && q.SecondElementName.compare("_") == 0 || 
					q.FirstElementName.compare(q.SecondElementName) != 0	)
					for(int i=0;i<list.size();i++){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName.compare(q.SecondElementName) != 0)
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
						}
			}
		}
		break;
		   }
	case 1:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
					col1.push_back(c1);
					col2.push_back(c2);
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end()){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() ){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() ){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(	q.FirstElementName.compare("_") == 0 && q.SecondElementName.compare("_") == 0 || 
					q.FirstElementName.compare(q.SecondElementName) != 0	)
					for(int i=0;i<list.size();i++){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName.compare(q.SecondElementName) != 0)
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
			}
		}
		break;
		   }
	case 2:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
					col1.push_back(c1);
					col2.push_back(c2);	
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(	q.FirstElementName.compare("_") == 0 && q.SecondElementName.compare("_") == 0 || 
					q.FirstElementName.compare(q.SecondElementName) != 0	)
					for(int i=0;i<list.size();i++){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName.compare(q.SecondElementName) != 0)
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
			}
		}
		break;
		   }
	case 3:{// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
					find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
					col1.push_back(c1);
					col2.push_back(c2);	
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), i) != tcol2.end()){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), i) != tcol2.end()){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(	q.FirstElementName.compare("_") == 0 && q.SecondElementName.compare("_") == 0 || 
					q.FirstElementName.compare(q.SecondElementName) != 0	)
					for(int i=0;i<list.size();i++){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end()){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end()){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end()){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName.compare(q.SecondElementName) != 0)
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
									find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end()){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
			}
		}
		break;
		   }
	}

	queryTree.at(index).table.push_back(col1);
	queryTree.at(index).table.push_back(col2);
}

void QueryProcessor::QueryFollowsStar(funcQuery_t q, int index, queryTreeNode_t finalTable){
	vector<int> col1, col2, tcol1, tcol2;

	int totalLineNum = (*pkb).getTotalLineNum();
	vector<pair<int,int>> list = (*pkb).getFollowsStarList();
	vector<vector<int>> matrix = (*pkb).getFollowsStarMatrix();

	AST ast = (*pkb).getAST();

	int colCase = 0;
	vector<string>::iterator it1 = find(finalTable.colName.begin(), finalTable.colName.end(), q.FirstElementName), 
		it2 = find(finalTable.colName.begin(), finalTable.colName.end(), q.SecondElementName);

	if(  it1 != finalTable.colName.end() ){
		colCase+=1;
		int pos = it1 - finalTable.colName.begin();
		tcol1 = finalTable.table.at(pos);
	}
	if(  it2 != finalTable.colName.end() ){
		colCase+=2;
		int pos = it2 - finalTable.colName.begin();
		tcol2 = finalTable.table.at(pos);
	}

	switch(colCase){
	case 0:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				col1.push_back(c1);
				col2.push_back(c2);	
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						col1.push_back(c1);
						col2.push_back(i);
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						col1.push_back(c1);
						col2.push_back(i);
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						col1.push_back(i);
						col2.push_back(c2);
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						col1.push_back(i);
						col2.push_back(c2);
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(	q.FirstElementName.compare("_") == 0 && q.SecondElementName.compare("_") == 0 || 
					q.FirstElementName.compare(q.SecondElementName) != 0	)
					for(int i=0;i<list.size();i++){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName.compare(q.SecondElementName) != 0)
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
						}
			}
		}
		break;
		   }
	case 1:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
					col1.push_back(c1);
					col2.push_back(c2);
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end()){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() ){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() ){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(	q.FirstElementName.compare("_") == 0 && q.SecondElementName.compare("_") == 0 || 
					q.FirstElementName.compare(q.SecondElementName) != 0	)
					for(int i=0;i<list.size();i++){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName.compare(q.SecondElementName) != 0)
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
			}
		}
		break;
		   }
	case 2:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
					col1.push_back(c1);
					col2.push_back(c2);	
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(	q.FirstElementName.compare("_") == 0 && q.SecondElementName.compare("_") == 0 || 
					q.FirstElementName.compare(q.SecondElementName) != 0	)
					for(int i=0;i<list.size();i++){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName.compare(q.SecondElementName) != 0)
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
			}
		}
		break;
		   }
	case 3:{// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
					find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
					col1.push_back(c1);
					col2.push_back(c2);	
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), i) != tcol2.end()){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), i) != tcol2.end()){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(	q.FirstElementName.compare("_") == 0 && q.SecondElementName.compare("_") == 0 || 
					q.FirstElementName.compare(q.SecondElementName) != 0	)
					for(int i=0;i<list.size();i++){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end()){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end()){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end()){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName.compare(q.SecondElementName) != 0)
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
									find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end()){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
			}
		}
		break;
		   }
	}

	queryTree.at(index).table.push_back(col1);
	queryTree.at(index).table.push_back(col2);
}

void QueryProcessor::QueryParent(funcQuery_t q, int index, queryTreeNode_t finalTable){
	vector<int> col1, col2, tcol1, tcol2;

	int totalLineNum = (*pkb).getTotalLineNum();
	vector<pair<int,int>> list = (*pkb).getParentList();
	vector<vector<int>> matrix = (*pkb).getParentMatrix();

	AST ast = (*pkb).getAST();

	int colCase = 0;
	vector<string>::iterator it1 = find(finalTable.colName.begin(), finalTable.colName.end(), q.FirstElementName), 
		it2 = find(finalTable.colName.begin(), finalTable.colName.end(), q.SecondElementName);

	if(  it1 != finalTable.colName.end() ){
		colCase+=1;
		int pos = it1 - finalTable.colName.begin();
		tcol1 = finalTable.table.at(pos);
	}
	if(  it2 != finalTable.colName.end() ){
		colCase+=2;
		int pos = it2 - finalTable.colName.begin();
		tcol2 = finalTable.table.at(pos);
	}

	switch(colCase){
	case 0:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				col1.push_back(c1);
				col2.push_back(c2);	
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						col1.push_back(c1);
						col2.push_back(i);
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						col1.push_back(c1);
						col2.push_back(i);
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						col1.push_back(i);
						col2.push_back(c2);
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						col1.push_back(i);
						col2.push_back(c2);
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(	q.FirstElementName.compare("_") == 0 && q.SecondElementName.compare("_") == 0 || 
					q.FirstElementName.compare(q.SecondElementName) != 0	)
					for(int i=0;i<list.size();i++){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName.compare(q.SecondElementName) != 0)
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
						}
			}
		}
		break;
		   }
	case 1:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
					col1.push_back(c1);
					col2.push_back(c2);
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end()){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() ){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() ){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(	q.FirstElementName.compare("_") == 0 && q.SecondElementName.compare("_") == 0 || 
					q.FirstElementName.compare(q.SecondElementName) != 0	)
					for(int i=0;i<list.size();i++){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName.compare(q.SecondElementName) != 0)
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
			}
		}
		break;
		   }
	case 2:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
					col1.push_back(c1);
					col2.push_back(c2);	
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(	q.FirstElementName.compare("_") == 0 && q.SecondElementName.compare("_") == 0 || 
					q.FirstElementName.compare(q.SecondElementName) != 0	)
					for(int i=0;i<list.size();i++){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName.compare(q.SecondElementName) != 0)
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
			}
		}
		break;
		   }
	case 3:{// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
					find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
					col1.push_back(c1);
					col2.push_back(c2);	
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), i) != tcol2.end()){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), i) != tcol2.end()){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(	q.FirstElementName.compare("_") == 0 && q.SecondElementName.compare("_") == 0 || 
					q.FirstElementName.compare(q.SecondElementName) != 0	)
					for(int i=0;i<list.size();i++){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end()){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end()){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end()){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName.compare(q.SecondElementName) != 0)
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
									find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end()){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
			}
		}
		break;
		   }
	}

	queryTree.at(index).table.push_back(col1);
	queryTree.at(index).table.push_back(col2);
}

void QueryProcessor::QueryParentStar(funcQuery_t q, int index, queryTreeNode_t finalTable){
	vector<int> col1, col2, tcol1, tcol2;

	int totalLineNum = (*pkb).getTotalLineNum();
	vector<pair<int,int>> list = (*pkb).getParentStarList();
	vector<vector<int>> matrix = (*pkb).getParentStarMatrix();

	AST ast = (*pkb).getAST();

	int colCase = 0;
	vector<string>::iterator it1 = find(finalTable.colName.begin(), finalTable.colName.end(), q.FirstElementName), 
		it2 = find(finalTable.colName.begin(), finalTable.colName.end(), q.SecondElementName);

	if(  it1 != finalTable.colName.end() ){
		colCase+=1;
		int pos = it1 - finalTable.colName.begin();
		tcol1 = finalTable.table.at(pos);
	}
	if(  it2 != finalTable.colName.end() ){
		colCase+=2;
		int pos = it2 - finalTable.colName.begin();
		tcol2 = finalTable.table.at(pos);
	}

	switch(colCase){
	case 0:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				col1.push_back(c1);
				col2.push_back(c2);	
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						col1.push_back(c1);
						col2.push_back(i);
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						col1.push_back(c1);
						col2.push_back(i);
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						col1.push_back(i);
						col2.push_back(c2);
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						col1.push_back(i);
						col2.push_back(c2);
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(	q.FirstElementName.compare("_") == 0 && q.SecondElementName.compare("_") == 0 || 
					q.FirstElementName.compare(q.SecondElementName) != 0	)
					for(int i=0;i<list.size();i++){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName.compare(q.SecondElementName) != 0)
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
						}
			}
		}
		break;
		   }
	case 1:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
					col1.push_back(c1);
					col2.push_back(c2);
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end()){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() ){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() ){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(	q.FirstElementName.compare("_") == 0 && q.SecondElementName.compare("_") == 0 || 
					q.FirstElementName.compare(q.SecondElementName) != 0	)
					for(int i=0;i<list.size();i++){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName.compare(q.SecondElementName) != 0)
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
			}
		}
		break;
		   }
	case 2:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
					col1.push_back(c1);
					col2.push_back(c2);	
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(	q.FirstElementName.compare("_") == 0 && q.SecondElementName.compare("_") == 0 || 
					q.FirstElementName.compare(q.SecondElementName) != 0	)
					for(int i=0;i<list.size();i++){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName.compare(q.SecondElementName) != 0)
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
			}
		}
		break;
		   }
	case 3:{// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
					find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
					col1.push_back(c1);
					col2.push_back(c2);	
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), i) != tcol2.end()){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), i) != tcol2.end()){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(	q.FirstElementName.compare("_") == 0 && q.SecondElementName.compare("_") == 0 || 
					q.FirstElementName.compare(q.SecondElementName) != 0	)
					for(int i=0;i<list.size();i++){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end()){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end()){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end()){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName.compare(q.SecondElementName) != 0)
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
									find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end()){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
			}
		}
		break;
		   }
	}

	queryTree.at(index).table.push_back(col1);
	queryTree.at(index).table.push_back(col2);
}

void QueryProcessor::QueryModifies(funcQuery_t q, int index, queryTreeNode_t finalTable){
	vector<pair<int,int>> list = (*pkb).getFullModifiesTable();
	vector<pair<int,int>> procModifiesList = (*pkb).getPModifiesTableV2();
	int totalLineNum = (*pkb).getTotalLineNum();
	ProcTable procTable = (*pkb).getProcTable();

	VarTable varTable = (*pkb).getVarTable();
	AST ast = (*pkb).getAST();

	vector<int> col1, col2 , tcol1, tcol2;
	int colCase = 0;
	string FirstElementName = queryTree.at(index).colName.at(0), SecondElementName = queryTree.at(index).colName.at(1);
	vector<string>::iterator it1 = find(finalTable.colName.begin(), finalTable.colName.end(), FirstElementName), 
		it2 = find(finalTable.colName.begin(), finalTable.colName.end(), SecondElementName);

	if(  it1 != finalTable.colName.end() ){
		colCase+=1;
		int pos = it1 - finalTable.colName.begin();
		tcol1 = finalTable.table.at(pos);
	}
	if(  it2 != finalTable.colName.end() ){
		colCase+=2;
		int pos = it2 - finalTable.colName.begin();
		tcol2 = finalTable.table.at(pos);
	}

	switch(colCase){
	case 0:{
		// First arg is procedure
		if(q.FirstElementType == "Procedure"){
			// Case Modifies(p,v) || Case Modifies(p,_)
			if(q.SecondElementType == "Variable" || q.SecondElementName == "_"){
				for(int i=0;i<procModifiesList.size();i++){
					col1.push_back(procModifiesList.at(i).first);
					col2.push_back(procModifiesList.at(i).second);
				}
			}
			// Case Modifies(p, "x")
			else{
				for(int i=0;i<procModifiesList.size();i++){
					int v2 = varTable.getVarIndex(q.SecondElementName);
					if(procModifiesList.at(i).second == v2){
						col1.push_back(procModifiesList.at(i).first);
						col2.push_back(procModifiesList.at(i).second);
					}
				}
			}
		}
		else if(q.FirstElementType == "String"){
			if(q.SecondElementType == "Variable" || q.SecondElementName == "_"){
				for(int i=0;i<procModifiesList.size();i++){
					int p = procTable.getProIndex(q.FirstElementName);
					if(procModifiesList.at(i).first == p){
						col1.push_back(procModifiesList.at(i).first);
						col2.push_back(procModifiesList.at(i).second);
					}
				}
			}
			else{
				for(int i=0;i<procModifiesList.size();i++){
					int v2 = varTable.getVarIndex(q.SecondElementName);
					int p = procTable.getProIndex(q.FirstElementName);
					if(procModifiesList.at(i).first == p && procModifiesList.at(i).second == v2){
						col1.push_back(procModifiesList.at(i).first);
						col2.push_back(procModifiesList.at(i).second);
					}
				}
			}
		}
		// First arg is constant
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			// Case Modifies(1,v)
			if(q.SecondElementType == "Variable"){
				for(int i=0;i<list.size();i++)
					if(list.at(i).first == c1){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			else{
				// Case Modifies(1,_)
				if(q.SecondElementName.compare("_") == 0){
					for(int i=0;i<list.size();i++)
						if(list.at(i).first == c1){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
				}
				// Case Modifies(1,"x")
				else{
					int v2 = varTable.getVarIndex(q.SecondElementName);
					if(isInList(c1,v2,list)){
						col1.push_back(c1);
						col2.push_back(v2);
					}
				}
			}
		}
		// First arg is not constant.
		else{
			// First arg is statement.
			if(q.FirstElementType.compare("Statement") == 0){
				// Case Modifies(s,v)
				if(q.SecondElementType == "Variable"){
					for(int i=0;i<list.size();i++){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
				else{
					// Case Modifies(s,_)
					if(q.SecondElementName.compare("_") == 0){
						for(int i=0;i<list.size();i++){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
					// Case Modifies(s,"x")
					else{
						int v2 = varTable.getVarIndex(q.SecondElementName);
						for(int i=0;i<list.size();i++)
							if(list.at(i).second == v2){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
					}
				}
			}
			// First arg is not statement.
			else{
				// Case Modifies(a/w,v)
				if(q.SecondElementType == "Variable"){
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0){	
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
				}
				else{
					// Case Modifies(a/w,_)
					if(q.SecondElementName.compare("_") == 0){
						for(int i=0;i<list.size();i++)
							if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0){	
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
					}
					// Case Modifies(a/w,"x")
					else{
						int v2 = varTable.getVarIndex(q.SecondElementName);
						for(int i=0;i<list.size();i++)
							if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0 &&
								list.at(i).second == v2){					
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
							}
					}
				}
			}
		}
		break;
		   }
	case 1:{
		// First arg is procedure
		if(q.FirstElementType == "Procedure"){
			// Case Modifies(p,v) || Case Modifies(p,_)
			if(q.SecondElementType == "Variable" || q.SecondElementName == "_"){
				for(int i=0;i<procModifiesList.size();i++){
					if( find(tcol1.begin(), tcol1.end(), procModifiesList.at(i).first) != tcol1.end() ){
						col1.push_back(procModifiesList.at(i).first);
						col2.push_back(procModifiesList.at(i).second);
					}
				}
			}
			// Case Modifies(p, "x")
			else{
				for(int i=0;i<procModifiesList.size();i++){
					int v2 = varTable.getVarIndex(q.SecondElementName);
					if(procModifiesList.at(i).second == v2){
						if( find(tcol1.begin(), tcol1.end(), procModifiesList.at(i).first) != tcol1.end() ){
							col1.push_back(procModifiesList.at(i).first);
							col2.push_back(procModifiesList.at(i).second);
						}
					}
				}
			}
		}
		else if(q.FirstElementType == "String"){
			if(q.SecondElementType == "Variable" || q.SecondElementName == "_"){
				for(int i=0;i<procModifiesList.size();i++){
					int p = procTable.getProIndex(q.FirstElementName);
					if(procModifiesList.at(i).first == p){
						if( find(tcol1.begin(), tcol1.end(), procModifiesList.at(i).first) != tcol1.end() ){
							col1.push_back(procModifiesList.at(i).first);
							col2.push_back(procModifiesList.at(i).second);
						}
					}
				}
			}
			else{
				for(int i=0;i<procModifiesList.size();i++){
					int v2 = varTable.getVarIndex(q.SecondElementName);
					int p = procTable.getProIndex(q.FirstElementName);
					if(procModifiesList.at(i).first == p && procModifiesList.at(i).second == v2){
						if( find(tcol1.begin(), tcol1.end(), procModifiesList.at(i).first) != tcol1.end() ){
							col1.push_back(procModifiesList.at(i).first);
							col2.push_back(procModifiesList.at(i).second);
						}
					}
				}
			}
		}
		// First arg is constant
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			// Case Modifies(1,v)
			if(q.SecondElementType == "Variable"){
				for(int i=0;i<list.size();i++)
					if(list.at(i).first == c1){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			else{
				// Case Modifies(1,_)
				if(q.SecondElementName.compare("_") == 0){
					for(int i=0;i<list.size();i++)
						if(list.at(i).first == c1){
							if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
				}
				// Case Modifies(1,"x")
				else{
					int v2 = varTable.getVarIndex(q.SecondElementName);
					if(isInList(c1,v2,list)){
						if( find(tcol1.begin(), tcol1.end(), v2) != tcol1.end() ){
							col1.push_back(c1);
							col2.push_back(v2);
						}
					}
				}
			}
		}
		// First arg is not constant.
		else{
			// First arg is statement.
			if(q.FirstElementType.compare("Statement") == 0){
				// Case Modifies(s,v)
				if(q.SecondElementType == "Variable"){
					for(int i=0;i<list.size();i++){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
				else{
					// Case Modifies(s,_)
					if(q.SecondElementName.compare("_") == 0){
						for(int i=0;i<list.size();i++){
							if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
					}
					// Case Modifies(s,"x")
					else{
						int v2 = varTable.getVarIndex(q.SecondElementName);
						for(int i=0;i<list.size();i++)
							if(list.at(i).second == v2){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
							}
					}
				}
			}
			// First arg is not statement.
			else{
				// Case Modifies(a/w,v)
				if(q.SecondElementType == "Variable"){
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0){	
							if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
				}
				else{
					// Case Modifies(a/w,_)
					if(q.SecondElementName.compare("_") == 0){
						for(int i=0;i<list.size();i++)
							if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0){	
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
							}
					}
					// Case Modifies(a/w,"x")
					else{
						int v2 = varTable.getVarIndex(q.SecondElementName);
						for(int i=0;i<list.size();i++)
							if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0 &&
								list.at(i).second == v2){					
									if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
										col1.push_back(list.at(i).first);
										col2.push_back(list.at(i).second);
									}
							}
					}
				}
			}
		}
		break;
		   }
	case 2:{
		// First arg is procedure
		if(q.FirstElementType == "Procedure"){
			// Case Modifies(p,v) || Case Modifies(p,_)
			if(q.SecondElementType == "Variable" || q.SecondElementName == "_"){
				for(int i=0;i<procModifiesList.size();i++){
					if( find(tcol2.begin(), tcol2.end(), procModifiesList.at(i).second) != tcol2.end() ){
						col1.push_back(procModifiesList.at(i).first);
						col2.push_back(procModifiesList.at(i).second);
					}
				}
			}
			// Case Modifies(p, "x")
			else{
				for(int i=0;i<procModifiesList.size();i++){
					int v2 = varTable.getVarIndex(q.SecondElementName);
					if(procModifiesList.at(i).second == v2){
						if( find(tcol2.begin(), tcol2.end(), procModifiesList.at(i).second) != tcol2.end() ){
							col1.push_back(procModifiesList.at(i).first);
							col2.push_back(procModifiesList.at(i).second);
						}
					}
				}
			}
		}
		else if(q.FirstElementType == "String"){
			if(q.SecondElementType == "Variable" || q.SecondElementName == "_"){
				for(int i=0;i<procModifiesList.size();i++){
					int p = procTable.getProIndex(q.FirstElementName);
					if(procModifiesList.at(i).first == p){
						if( find(tcol2.begin(), tcol2.end(), procModifiesList.at(i).second) != tcol2.end() ){
							col1.push_back(procModifiesList.at(i).first);
							col2.push_back(procModifiesList.at(i).second);
						}
					}
				}
			}
			else{
				for(int i=0;i<procModifiesList.size();i++){
					int v2 = varTable.getVarIndex(q.SecondElementName);
					int p = procTable.getProIndex(q.FirstElementName);
					if(procModifiesList.at(i).first == p && procModifiesList.at(i).second == v2){
						if( find(tcol2.begin(), tcol2.end(), procModifiesList.at(i).second) != tcol2.end() ){
							col1.push_back(procModifiesList.at(i).first);
							col2.push_back(procModifiesList.at(i).second);
						}
					}
				}
			}
		}
		// First arg is constant
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			// Case Modifies(1,v)
			if(q.SecondElementType == "Variable"){
				for(int i=0;i<list.size();i++)
					if(list.at(i).first == c1){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			else{
				// Case Modifies(1,_)
				if(q.SecondElementName.compare("_") == 0){
					for(int i=0;i<list.size();i++)
						if(list.at(i).first == c1){
							if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
				}
				// Case Modifies(1,"x")
				else{
					int v2 = varTable.getVarIndex(q.SecondElementName);
					if(isInList(c1,v2,list)){
						if( find(tcol2.begin(), tcol2.end(), v2) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(v2);
						}
					}
				}
			}
		}
		// First arg is not constant.
		else{
			// First arg is statement.
			if(q.FirstElementType.compare("Statement") == 0){
				// Case Modifies(s,v)
				if(q.SecondElementType == "Variable"){
					for(int i=0;i<list.size();i++){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
				else{
					// Case Modifies(s,_)
					if(q.SecondElementName.compare("_") == 0){
						for(int i=0;i<list.size();i++){
							if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
					}
					// Case Modifies(s,"x")
					else{
						int v2 = varTable.getVarIndex(q.SecondElementName);
						for(int i=0;i<list.size();i++)
							if(list.at(i).second == v2){
								if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
							}
					}
				}
			}
			// First arg is not statement.
			else{
				// Case Modifies(a/w,v)
				if(q.SecondElementType == "Variable"){
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0){	
							if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
				}
				else{
					// Case Modifies(a/w,_)
					if(q.SecondElementName.compare("_") == 0){
						for(int i=0;i<list.size();i++)
							if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0){	
								if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
							}
					}
					// Case Modifies(a/w,"x")
					else{
						int v2 = varTable.getVarIndex(q.SecondElementName);
						for(int i=0;i<list.size();i++)
							if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0 &&
								list.at(i).second == v2){					
									if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
										col1.push_back(list.at(i).first);
										col2.push_back(list.at(i).second);
									}
							}
					}
				}
			}
		}
		break;
		   }
	case 3:{
		// First arg is procedure
		if(q.FirstElementType == "Procedure"){
			// Case Modifies(p,v) || Case Modifies(p,_)
			if(q.SecondElementType == "Variable" || q.SecondElementName == "_"){
				for(int i=0;i<procModifiesList.size();i++){
					if( find(tcol1.begin(), tcol1.end(), procModifiesList.at(i).first) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), procModifiesList.at(i).second) != tcol2.end() ){
						col1.push_back(procModifiesList.at(i).first);
						col2.push_back(procModifiesList.at(i).second);
					}
				}
			}
			// Case Modifies(p, "x")
			else{
				for(int i=0;i<procModifiesList.size();i++){
					int v2 = varTable.getVarIndex(q.SecondElementName);
					if(procModifiesList.at(i).second == v2){
						if( find(tcol1.begin(), tcol1.end(), procModifiesList.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), procModifiesList.at(i).second) != tcol2.end() ){
							col1.push_back(procModifiesList.at(i).first);
							col2.push_back(procModifiesList.at(i).second);
						}
					}
				}
			}
		}
		else if(q.FirstElementType == "String"){
			if(q.SecondElementType == "Variable" || q.SecondElementName == "_"){
				for(int i=0;i<procModifiesList.size();i++){
					int p = procTable.getProIndex(q.FirstElementName);
					if(procModifiesList.at(i).first == p){
						if( find(tcol1.begin(), tcol1.end(), procModifiesList.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), procModifiesList.at(i).second) != tcol2.end() ){
							col1.push_back(procModifiesList.at(i).first);
							col2.push_back(procModifiesList.at(i).second);
						}
					}
				}
			}
			else{
				for(int i=0;i<procModifiesList.size();i++){
					int v2 = varTable.getVarIndex(q.SecondElementName);
					int p = procTable.getProIndex(q.FirstElementName);
					if(procModifiesList.at(i).first == p && procModifiesList.at(i).second == v2){
						if( find(tcol1.begin(), tcol1.end(), procModifiesList.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), procModifiesList.at(i).second) != tcol2.end() ){
							col1.push_back(procModifiesList.at(i).first);
							col2.push_back(procModifiesList.at(i).second);
						}
					}
				}
			}
		}
		// First arg is constant
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			// Case Modifies(1,v)
			if(q.SecondElementType == "Variable"){
				for(int i=0;i<list.size();i++)
					if(list.at(i).first == c1){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			else{
				// Case Modifies(1,_)
				if(q.SecondElementName.compare("_") == 0){
					for(int i=0;i<list.size();i++)
						if(list.at(i).first == c1){
							if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
								find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
				}
				// Case Modifies(1,"x")
				else{
					int v2 = varTable.getVarIndex(q.SecondElementName);
					if(isInList(c1,v2,list)){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), v2) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(v2);
						}
					}
				}
			}
		}
		// First arg is not constant.
		else{
			// First arg is statement.
			if(q.FirstElementType.compare("Statement") == 0){
				// Case Modifies(s,v)
				if(q.SecondElementType == "Variable"){
					for(int i=0;i<list.size();i++){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
				else{
					// Case Modifies(s,_)
					if(q.SecondElementName.compare("_") == 0){
						for(int i=0;i<list.size();i++){
							if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
								find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
					}
					// Case Modifies(s,"x")
					else{
						int v2 = varTable.getVarIndex(q.SecondElementName);
						for(int i=0;i<list.size();i++)
							if(list.at(i).second == v2){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
									find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
							}
					}
				}
			}
			// First arg is not statement.
			else{
				// Case Modifies(a/w,v)
				if(q.SecondElementType == "Variable"){
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0){	
							if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() && 
								find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
				}
				else{
					// Case Modifies(a/w,_)
					if(q.SecondElementName.compare("_") == 0){
						for(int i=0;i<list.size();i++)
							if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0){	
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() && 
									find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
							}
					}
					// Case Modifies(a/w,"x")
					else{
						int v2 = varTable.getVarIndex(q.SecondElementName);
						for(int i=0;i<list.size();i++)
							if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0 &&
								list.at(i).second == v2){					
									if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
										find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
										col1.push_back(list.at(i).first);
										col2.push_back(list.at(i).second);
									}
							}
					}
				}
			}
		}
		break;
		   }
	}

	queryTree.at(index).table.push_back(col1);
	queryTree.at(index).table.push_back(col2);
}

void QueryProcessor::QueryUses(funcQuery_t q, int index, queryTreeNode_t finalTable){
	vector<pair<int,int>> list = (*pkb).getFullUsesTable();
	vector<pair<int,int>> procUsesList = (*pkb).getPUsesTableV2();
	int totalLineNum = (*pkb).getTotalLineNum();
	ProcTable procTable = (*pkb).getProcTable();

	VarTable varTable = (*pkb).getVarTable();
	AST ast = (*pkb).getAST();

	vector<int> col1, col2 , tcol1, tcol2;
	string FirstElementName = queryTree.at(index).colName.at(0), SecondElementName = queryTree.at(index).colName.at(1);
	int colCase = 0;
	vector<string>::iterator it1 = find(finalTable.colName.begin(), finalTable.colName.end(), FirstElementName), 
		it2 = find(finalTable.colName.begin(), finalTable.colName.end(), SecondElementName);

	if(  it1 != finalTable.colName.end() ){
		colCase+=1;
		int pos = it1 - finalTable.colName.begin();
		tcol1 = finalTable.table.at(pos);
	}
	if(  it2 != finalTable.colName.end() ){
		colCase+=2;
		int pos = it2 - finalTable.colName.begin();
		tcol2 = finalTable.table.at(pos);
	}

	switch(colCase){
	case 0:{
		// First arg is procedure
		if(q.FirstElementType == "Procedure"){
			// Case Uses(p,v) || Case Uses(p,_)
			if(q.SecondElementType == "Variable" || q.SecondElementName == "_"){
				for(int i=0;i<procUsesList.size();i++){
					col1.push_back(procUsesList.at(i).first);
					col2.push_back(procUsesList.at(i).second);
				}
			}
			// Case Uses(p, "x")
			else{
				for(int i=0;i<procUsesList.size();i++){
					int v2 = varTable.getVarIndex(q.SecondElementName);
					if(procUsesList.at(i).second == v2){
						col1.push_back(procUsesList.at(i).first);
						col2.push_back(procUsesList.at(i).second);
					}
				}
			}
		}
		else if(q.FirstElementType == "String"){
			if(q.SecondElementType == "Variable" || q.SecondElementName == "_"){
				for(int i=0;i<procUsesList.size();i++){
					int p = procTable.getProIndex(q.FirstElementName);
					if(procUsesList.at(i).first == p){
						col1.push_back(procUsesList.at(i).first);
						col2.push_back(procUsesList.at(i).second);
					}
				}
			}
			else{
				for(int i=0;i<procUsesList.size();i++){
					int v2 = varTable.getVarIndex(q.SecondElementName);
					int p = procTable.getProIndex(q.FirstElementName);
					if(procUsesList.at(i).first == p && procUsesList.at(i).second == v2){
						col1.push_back(procUsesList.at(i).first);
						col2.push_back(procUsesList.at(i).second);
					}
				}
			}
		}
		// First arg is constant
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			// Case Uses(1,v)
			if(q.SecondElementType == "Variable"){
				for(int i=0;i<list.size();i++)
					if(list.at(i).first == c1){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			else{
				// Case Uses(1,_)
				if(q.SecondElementName.compare("_") == 0){
					for(int i=0;i<list.size();i++)
						if(list.at(i).first == c1){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
				}
				// Case Uses(1,"x")
				else{
					int v2 = varTable.getVarIndex(q.SecondElementName);
					if(isInList(c1,v2,list)){
						col1.push_back(c1);
						col2.push_back(v2);
					}
				}
			}
		}
		// First arg is not constant.
		else{
			// First arg is statement.
			if(q.FirstElementType.compare("Statement") == 0){
				// Case Uses(s,v)
				if(q.SecondElementType == "Variable"){
					for(int i=0;i<list.size();i++){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
				else{
					// Case Uses(s,_)
					if(q.SecondElementName.compare("_") == 0){
						for(int i=0;i<list.size();i++){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
					// Case Uses(s,"x")
					else{
						int v2 = varTable.getVarIndex(q.SecondElementName);
						for(int i=0;i<list.size();i++)
							if(list.at(i).second == v2){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
					}
				}
			}
			// First arg is not statement.
			else{
				// Case Uses(a/w,v)
				if(q.SecondElementType == "Variable"){
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0){	
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
				}
				else{
					// Case Uses(a/w,_)
					if(q.SecondElementName.compare("_") == 0){
						for(int i=0;i<list.size();i++)
							if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0){	
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
					}
					// Case Uses(a/w,"x")
					else{
						int v2 = varTable.getVarIndex(q.SecondElementName);
						for(int i=0;i<list.size();i++)
							if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0 &&
								list.at(i).second == v2){					
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
							}
					}
				}
			}
		}
		break;
		   }
	case 1:{
		// First arg is procedure
		if(q.FirstElementType == "Procedure"){
			// Case Uses(p,v) || Case Uses(p,_)
			if(q.SecondElementType == "Variable" || q.SecondElementName == "_"){
				for(int i=0;i<procUsesList.size();i++){
					if( find(tcol1.begin(), tcol1.end(), procUsesList.at(i).first) != tcol1.end() ){
						col1.push_back(procUsesList.at(i).first);
						col2.push_back(procUsesList.at(i).second);
					}
				}
			}
			// Case Uses(p, "x")
			else{
				for(int i=0;i<procUsesList.size();i++){
					int v2 = varTable.getVarIndex(q.SecondElementName);
					if(procUsesList.at(i).second == v2){
						if( find(tcol1.begin(), tcol1.end(), procUsesList.at(i).first) != tcol1.end() ){
							col1.push_back(procUsesList.at(i).first);
							col2.push_back(procUsesList.at(i).second);
						}
					}
				}
			}
		}
		else if(q.FirstElementType == "String"){
			if(q.SecondElementType == "Variable" || q.SecondElementName == "_"){
				for(int i=0;i<procUsesList.size();i++){
					int p = procTable.getProIndex(q.FirstElementName);
					if(procUsesList.at(i).first == p){
						if( find(tcol1.begin(), tcol1.end(), procUsesList.at(i).first) != tcol1.end() ){
							col1.push_back(procUsesList.at(i).first);
							col2.push_back(procUsesList.at(i).second);
						}
					}
				}
			}
			else{
				for(int i=0;i<procUsesList.size();i++){
					int v2 = varTable.getVarIndex(q.SecondElementName);
					int p = procTable.getProIndex(q.FirstElementName);
					if(procUsesList.at(i).first == p && procUsesList.at(i).second == v2){
						if( find(tcol1.begin(), tcol1.end(), procUsesList.at(i).first) != tcol1.end() ){
							col1.push_back(procUsesList.at(i).first);
							col2.push_back(procUsesList.at(i).second);
						}
					}
				}
			}
		}
		// First arg is constant
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			// Case Uses(1,v)
			if(q.SecondElementType == "Variable"){
				for(int i=0;i<list.size();i++)
					if(list.at(i).first == c1){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			else{
				// Case Uses(1,_)
				if(q.SecondElementName.compare("_") == 0){
					for(int i=0;i<list.size();i++)
						if(list.at(i).first == c1){
							if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
				}
				// Case Uses(1,"x")
				else{
					int v2 = varTable.getVarIndex(q.SecondElementName);
					if(isInList(c1,v2,list)){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
							col1.push_back(c1);
							col2.push_back(v2);
						}
					}
				}
			}
		}
		// First arg is not constant.
		else{
			// First arg is statement.
			if(q.FirstElementType.compare("Statement") == 0){
				// Case Uses(s,v)
				if(q.SecondElementType == "Variable"){
					for(int i=0;i<list.size();i++){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
				else{
					// Case Uses(s,_)
					if(q.SecondElementName.compare("_") == 0){
						for(int i=0;i<list.size();i++){
							if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
					}
					// Case Uses(s,"x")
					else{
						int v2 = varTable.getVarIndex(q.SecondElementName);
						for(int i=0;i<list.size();i++)
							if(list.at(i).second == v2){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
							}
					}
				}
			}
			// First arg is not statement.
			else{
				// Case Uses(a/w,v)
				if(q.SecondElementType == "Variable"){
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0){	
							if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
				}
				else{
					// Case Uses(a/w,_)
					if(q.SecondElementName.compare("_") == 0){
						for(int i=0;i<list.size();i++)
							if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0){	
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
							}
					}
					// Case Uses(a/w,"x")
					else{
						int v2 = varTable.getVarIndex(q.SecondElementName);
						for(int i=0;i<list.size();i++)
							if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0 &&
								list.at(i).second == v2){					
									if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
										col1.push_back(list.at(i).first);
										col2.push_back(list.at(i).second);
									}
							}
					}
				}
			}
		}
		break;
		   }
	case 2:{
		// First arg is procedure
		if(q.FirstElementType == "Procedure"){
			// Case Uses(p,v) || Case Uses(p,_)
			if(q.SecondElementType == "Variable" || q.SecondElementName == "_"){
				for(int i=0;i<procUsesList.size();i++){
					if( find(tcol2.begin(), tcol2.end(), procUsesList.at(i).second) != tcol2.end() ){
						col1.push_back(procUsesList.at(i).first);
						col2.push_back(procUsesList.at(i).second);
					}
				}
			}
			// Case Uses(p, "x")
			else{
				for(int i=0;i<procUsesList.size();i++){
					int v2 = varTable.getVarIndex(q.SecondElementName);
					if(procUsesList.at(i).second == v2){
						if( find(tcol2.begin(), tcol2.end(), procUsesList.at(i).second) != tcol2.end() ){
							col1.push_back(procUsesList.at(i).first);
							col2.push_back(procUsesList.at(i).second);
						}
					}
				}
			}
		}
		else if(q.FirstElementType == "String"){
			if(q.SecondElementType == "Variable" || q.SecondElementName == "_"){
				for(int i=0;i<procUsesList.size();i++){
					int p = procTable.getProIndex(q.FirstElementName);
					if(procUsesList.at(i).first == p){
						if( find(tcol2.begin(), tcol2.end(), procUsesList.at(i).second) != tcol2.end() ){
							col1.push_back(procUsesList.at(i).first);
							col2.push_back(procUsesList.at(i).second);
						}
					}
				}
			}
			else{
				for(int i=0;i<procUsesList.size();i++){
					int v2 = varTable.getVarIndex(q.SecondElementName);
					int p = procTable.getProIndex(q.FirstElementName);
					if(procUsesList.at(i).first == p && procUsesList.at(i).second == v2){
						if( find(tcol2.begin(), tcol2.end(), procUsesList.at(i).second) != tcol2.end() ){
							col1.push_back(procUsesList.at(i).first);
							col2.push_back(procUsesList.at(i).second);
						}
					}
				}
			}
		}
		// First arg is constant
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			// Case Uses(1,v)
			if(q.SecondElementType == "Variable"){
				for(int i=0;i<list.size();i++)
					if(list.at(i).first == c1){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			else{
				// Case Uses(1,_)
				if(q.SecondElementName.compare("_") == 0){
					for(int i=0;i<list.size();i++)
						if(list.at(i).first == c1){
							if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
				}
				// Case Uses(1,"x")
				else{
					int v2 = varTable.getVarIndex(q.SecondElementName);
					if(isInList(c1,v2,list)){
						if( find(tcol2.begin(), tcol2.end(), v2) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(v2);
						}
					}
				}
			}
		}
		// First arg is not constant.
		else{
			// First arg is statement.
			if(q.FirstElementType.compare("Statement") == 0){
				// Case Uses(s,v)
				if(q.SecondElementType == "Variable"){
					for(int i=0;i<list.size();i++){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
				else{
					// Case Uses(s,_)
					if(q.SecondElementName.compare("_") == 0){
						for(int i=0;i<list.size();i++){
							if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
					}
					// Case Uses(s,"x")
					else{
						int v2 = varTable.getVarIndex(q.SecondElementName);
						for(int i=0;i<list.size();i++)
							if(list.at(i).second == v2){
								if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
							}
					}
				}
			}
			// First arg is not statement.
			else{
				// Case Uses(a/w,v)
				if(q.SecondElementType == "Variable"){
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0){	
							if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
				}
				else{
					// Case Uses(a/w,_)
					if(q.SecondElementName.compare("_") == 0){
						for(int i=0;i<list.size();i++)
							if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0){	
								if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
							}
					}
					// Case Uses(a/w,"x")
					else{
						int v2 = varTable.getVarIndex(q.SecondElementName);
						for(int i=0;i<list.size();i++)
							if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0 &&
								list.at(i).second == v2){					
									if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
										col1.push_back(list.at(i).first);
										col2.push_back(list.at(i).second);
									}
							}
					}
				}
			}
		}
		break;
		   }
	case 3:{
		// First arg is procedure
		if(q.FirstElementType == "Procedure"){
			// Case Uses(p,v) || Case Uses(p,_)
			if(q.SecondElementType == "Variable" || q.SecondElementName == "_"){
				for(int i=0;i<procUsesList.size();i++){
					if( find(tcol1.begin(), tcol1.end(), procUsesList.at(i).first) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), procUsesList.at(i).second) != tcol2.end() ){
						col1.push_back(procUsesList.at(i).first);
						col2.push_back(procUsesList.at(i).second);
					}
				}
			}
			// Case Uses(p, "x")
			else{
				for(int i=0;i<procUsesList.size();i++){
					int v2 = varTable.getVarIndex(q.SecondElementName);
					if(procUsesList.at(i).second == v2){
						if( find(tcol1.begin(), tcol1.end(), procUsesList.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), procUsesList.at(i).second) != tcol2.end() ){
							col1.push_back(procUsesList.at(i).first);
							col2.push_back(procUsesList.at(i).second);
						}
					}
				}
			}
		}
		else if(q.FirstElementType == "String"){
			if(q.SecondElementType == "Variable" || q.SecondElementName == "_"){
				for(int i=0;i<procUsesList.size();i++){
					int p = procTable.getProIndex(q.FirstElementName);
					if(procUsesList.at(i).first == p){
						if( find(tcol1.begin(), tcol1.end(), procUsesList.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), procUsesList.at(i).second) != tcol2.end() ){
							col1.push_back(procUsesList.at(i).first);
							col2.push_back(procUsesList.at(i).second);
						}
					}
				}
			}
			else{
				for(int i=0;i<procUsesList.size();i++){
					int v2 = varTable.getVarIndex(q.SecondElementName);
					int p = procTable.getProIndex(q.FirstElementName);
					if(procUsesList.at(i).first == p && procUsesList.at(i).second == v2){
						if( find(tcol1.begin(), tcol1.end(), procUsesList.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), procUsesList.at(i).second) != tcol2.end() ){
							col1.push_back(procUsesList.at(i).first);
							col2.push_back(procUsesList.at(i).second);
						}
					}
				}
			}
		}
		// First arg is constant
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			// Case Uses(1,v)
			if(q.SecondElementType == "Variable"){
				for(int i=0;i<list.size();i++)
					if(list.at(i).first == c1){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			else{
				// Case Uses(1,_)
				if(q.SecondElementName.compare("_") == 0){
					for(int i=0;i<list.size();i++)
						if(list.at(i).first == c1){
							if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
								find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
				}
				// Case Uses(1,"x")
				else{
					int v2 = varTable.getVarIndex(q.SecondElementName);
					if(isInList(c1,v2,list)){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), v2) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(v2);
						}
					}
				}
			}
		}
		// First arg is not constant.
		else{
			// First arg is statement.
			if(q.FirstElementType.compare("Statement") == 0){
				// Case Uses(s,v)
				if(q.SecondElementType == "Variable"){
					for(int i=0;i<list.size();i++){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
				else{
					// Case Uses(s,_)
					if(q.SecondElementName.compare("_") == 0){
						for(int i=0;i<list.size();i++){
							if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
								find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
					}
					// Case Uses(s,"x")
					else{
						int v2 = varTable.getVarIndex(q.SecondElementName);
						for(int i=0;i<list.size();i++)
							if(list.at(i).second == v2){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
									find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
							}
					}
				}
			}
			// First arg is not statement.
			else{
				// Case Uses(a/w,v)
				if(q.SecondElementType == "Variable"){
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0){	
							if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() && 
								find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
				}
				else{
					// Case Uses(a/w,_)
					if(q.SecondElementName.compare("_") == 0){
						for(int i=0;i<list.size();i++)
							if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0){	
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() && 
									find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
							}
					}
					// Case Uses(a/w,"x")
					else{
						int v2 = varTable.getVarIndex(q.SecondElementName);
						for(int i=0;i<list.size();i++)
							if(	q.FirstElementType.compare((*ast.getNodeFromLineNum(ast.getRoot(),list.at(i).first)).getNodeType()) == 0 &&
								list.at(i).second == v2){					
									if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
										find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
										col1.push_back(list.at(i).first);
										col2.push_back(list.at(i).second);
									}
							}
					}
				}
			}
		}
		break;
		   }
	}

	queryTree.at(index).table.push_back(col1);
	queryTree.at(index).table.push_back(col2);
}

void QueryProcessor::QueryCall(funcQuery_t q, int index, queryTreeNode_t finalTable){
	Calls calls = (*pkb).getCalls();
	vector<pair<int,int>> list = (*pkb).getCallsList();
	ProcTable procTable = (*pkb).getProcTable();

	vector<int> col1, col2 , tcol1, tcol2;
	string FirstElementName = queryTree.at(index).colName.at(0), SecondElementName = queryTree.at(index).colName.at(1);
	int colCase = 0;
	vector<string>::iterator it1 = find(finalTable.colName.begin(), finalTable.colName.end(), FirstElementName), 
		it2 = find(finalTable.colName.begin(), finalTable.colName.end(), SecondElementName);

	if(  it1 != finalTable.colName.end() ){
		colCase+=1;
		int pos = it1 - finalTable.colName.begin();
		tcol1 = finalTable.table.at(pos);
	}
	if(  it2 != finalTable.colName.end() ){
		colCase+=2;
		int pos = it2 - finalTable.colName.begin();
		tcol2 = finalTable.table.at(pos);
	}

	switch(colCase){
	case 0:{
		if(q.FirstElementType == "Procedure" && q.SecondElementType == "Procedure"){
			if(q.FirstElementName != q.SecondElementName)
				for(int i=0;i<list.size();i++){
					col1.push_back(list.at(i).first);
					col2.push_back(list.at(i).second);
				}
		}
		else if(q.FirstElementType == "Procedure"){
			if(q.SecondElementName == "_"){
				for(int i=0;i<list.size();i++){
					col1.push_back(list.at(i).first);
					col2.push_back(list.at(i).second);
				}
			}
			else{
				int proc2Idx = procTable.getProIndex(q.SecondElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).second == proc2Idx){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
		}
		else if(q.SecondElementType == "Procedure"){
			if(q.FirstElementName == "_"){
				for(int i=0;i<list.size();i++){
					col1.push_back(list.at(i).first);
					col2.push_back(list.at(i).second);
				}
			}
			else{
				int proc1Idx = procTable.getProIndex(q.FirstElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == proc1Idx){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
		}
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_"){
				for(int i=0;i<list.size();i++){
					col1.push_back(list.at(i).first);
					col2.push_back(list.at(i).second);
				}
			}
			else if(q.FirstElementName == "_"){
				int proc2Idx = procTable.getProIndex(q.SecondElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).second == proc2Idx){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else if(q.SecondElementName == "_"){
				int proc1Idx = procTable.getProIndex(q.FirstElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == proc1Idx){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				int procNum1 = procTable.getProIndex(q.FirstElementName), procNum2 = procTable.getProIndex(q.SecondElementName);
				if(calls.isCall(procNum1, procNum2)){
					col1.push_back(procNum1);
					col2.push_back(procNum2);
				}
			}
		}
		break;
		   }
	case 1:{
		if(q.FirstElementType == "Procedure" && q.SecondElementType == "Procedure"){
			if(q.FirstElementName != q.SecondElementName)
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
		}
		else if(q.FirstElementType == "Procedure"){
			if(q.SecondElementName == "_"){
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				int proc2Idx = procTable.getProIndex(q.SecondElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).second == proc2Idx){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		else if(q.SecondElementType == "Procedure"){
			if(q.FirstElementName == "_"){
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				int proc1Idx = procTable.getProIndex(q.FirstElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == proc1Idx){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_"){
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else if(q.FirstElementName == "_"){
				int proc2Idx = procTable.getProIndex(q.SecondElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).second == proc2Idx){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
			else if(q.SecondElementName == "_"){
				int proc1Idx = procTable.getProIndex(q.FirstElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == proc1Idx){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
			else{
				int procNum1 = procTable.getProIndex(q.FirstElementName), procNum2 = procTable.getProIndex(q.SecondElementName);
				if(calls.isCall(procNum1, procNum2)){
					if( find(tcol1.begin(), tcol1.end(), procNum1) != tcol1.end() ){
						col1.push_back(procNum1);
						col2.push_back(procNum2);
					}
				}
			}
		}
		break;
		   }
	case 2:{
		if(q.FirstElementType == "Procedure" && q.SecondElementType == "Procedure"){
			if(q.FirstElementName != q.SecondElementName)
				for(int i=0;i<list.size();i++){
					if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
		}
		else if(q.FirstElementType == "Procedure"){
			if(q.SecondElementName == "_"){
				for(int i=0;i<list.size();i++){
					if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				int proc2Idx = procTable.getProIndex(q.SecondElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).second == proc2Idx){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		else if(q.SecondElementType == "Procedure"){
			if(q.FirstElementName == "_"){
				for(int i=0;i<list.size();i++){
					if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				int proc1Idx = procTable.getProIndex(q.FirstElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == proc1Idx){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_"){
				for(int i=0;i<list.size();i++){
					if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else if(q.FirstElementName == "_"){
				int proc2Idx = procTable.getProIndex(q.SecondElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).second == proc2Idx){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
			else if(q.SecondElementName == "_"){
				int proc1Idx = procTable.getProIndex(q.FirstElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == proc1Idx){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
			else{
				int procNum1 = procTable.getProIndex(q.FirstElementName), procNum2 = procTable.getProIndex(q.SecondElementName);
				if(calls.isCall(procNum1, procNum2)){
					if( find(tcol2.begin(), tcol2.end(), procNum2) != tcol2.end() ){
						col1.push_back(procNum1);
						col2.push_back(procNum2);
					}
				}
			}
		}
		break;
		   }
	case 3:{
		if(q.FirstElementType == "Procedure" && q.SecondElementType == "Procedure"){
			if(q.FirstElementName != q.SecondElementName)
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
		}
		else if(q.FirstElementType == "Procedure"){
			if(q.SecondElementName == "_"){
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				int proc2Idx = procTable.getProIndex(q.SecondElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).second == proc2Idx){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		else if(q.SecondElementType == "Procedure"){
			if(q.FirstElementName == "_"){
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				int proc1Idx = procTable.getProIndex(q.FirstElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == proc1Idx){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_"){
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else if(q.FirstElementName == "_"){
				int proc2Idx = procTable.getProIndex(q.SecondElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).second == proc2Idx){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
			else if(q.SecondElementName == "_"){
				int proc1Idx = procTable.getProIndex(q.FirstElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == proc1Idx){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
			else{
				int procNum1 = procTable.getProIndex(q.FirstElementName), procNum2 = procTable.getProIndex(q.SecondElementName);
				if(calls.isCall(procNum1, procNum2)){
					if( find(tcol1.begin(), tcol1.end(), procNum1) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), procNum2) != tcol2.end() ){
						col1.push_back(procNum1);
						col2.push_back(procNum2);
					}
				}
			}
		}
		break;
		   }
	}

	queryTree.at(index).table.push_back(col1);
	queryTree.at(index).table.push_back(col2);
}

void QueryProcessor::QueryCallStar(funcQuery_t q, int index, queryTreeNode_t finalTable){
	Calls calls = (*pkb).getCalls();
	vector<pair<int,int>> list = (*pkb).getCallsStarList();
	ProcTable procTable = (*pkb).getProcTable();

	vector<int> col1, col2 , tcol1, tcol2;
	string FirstElementName = queryTree.at(index).colName.at(0), SecondElementName = queryTree.at(index).colName.at(1);
	int colCase = 0;
	vector<string>::iterator it1 = find(finalTable.colName.begin(), finalTable.colName.end(), FirstElementName), 
		it2 = find(finalTable.colName.begin(), finalTable.colName.end(), SecondElementName);

	if(  it1 != finalTable.colName.end() ){
		colCase+=1;
		int pos = it1 - finalTable.colName.begin();
		tcol1 = finalTable.table.at(pos);
	}
	if(  it2 != finalTable.colName.end() ){
		colCase+=2;
		int pos = it2 - finalTable.colName.begin();
		tcol2 = finalTable.table.at(pos);
	}
	
		switch(colCase){
	case 0:{
		if(q.FirstElementType == "Procedure" && q.SecondElementType == "Procedure"){
			if(q.FirstElementName != q.SecondElementName)
				for(int i=0;i<list.size();i++){
					col1.push_back(list.at(i).first);
					col2.push_back(list.at(i).second);
				}
		}
		else if(q.FirstElementType == "Procedure"){
			if(q.SecondElementName == "_"){
				for(int i=0;i<list.size();i++){
					col1.push_back(list.at(i).first);
					col2.push_back(list.at(i).second);
				}
			}
			else{
				int proc2Idx = procTable.getProIndex(q.SecondElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).second == proc2Idx){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
		}
		else if(q.SecondElementType == "Procedure"){
			if(q.FirstElementName == "_"){
				for(int i=0;i<list.size();i++){
					col1.push_back(list.at(i).first);
					col2.push_back(list.at(i).second);
				}
			}
			else{
				int proc1Idx = procTable.getProIndex(q.FirstElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == proc1Idx){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
		}
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_"){
				for(int i=0;i<list.size();i++){
					col1.push_back(list.at(i).first);
					col2.push_back(list.at(i).second);
				}
			}
			else if(q.FirstElementName == "_"){
				int proc2Idx = procTable.getProIndex(q.SecondElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).second == proc2Idx){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else if(q.SecondElementName == "_"){
				int proc1Idx = procTable.getProIndex(q.FirstElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == proc1Idx){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				int procNum1 = procTable.getProIndex(q.FirstElementName), procNum2 = procTable.getProIndex(q.SecondElementName);
				if(calls.isCall(procNum1, procNum2)){
					col1.push_back(procNum1);
					col2.push_back(procNum2);
				}
			}
		}
		break;
		   }
	case 1:{
		if(q.FirstElementType == "Procedure" && q.SecondElementType == "Procedure"){
			if(q.FirstElementName != q.SecondElementName)
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
		}
		else if(q.FirstElementType == "Procedure"){
			if(q.SecondElementName == "_"){
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				int proc2Idx = procTable.getProIndex(q.SecondElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).second == proc2Idx){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		else if(q.SecondElementType == "Procedure"){
			if(q.FirstElementName == "_"){
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				int proc1Idx = procTable.getProIndex(q.FirstElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == proc1Idx){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_"){
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else if(q.FirstElementName == "_"){
				int proc2Idx = procTable.getProIndex(q.SecondElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).second == proc2Idx){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
			else if(q.SecondElementName == "_"){
				int proc1Idx = procTable.getProIndex(q.FirstElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == proc1Idx){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
			else{
				int procNum1 = procTable.getProIndex(q.FirstElementName), procNum2 = procTable.getProIndex(q.SecondElementName);
				if(calls.isCall(procNum1, procNum2)){
					if( find(tcol1.begin(), tcol1.end(), procNum1) != tcol1.end() ){
						col1.push_back(procNum1);
						col2.push_back(procNum2);
					}
				}
			}
		}
		break;
		   }
	case 2:{
		if(q.FirstElementType == "Procedure" && q.SecondElementType == "Procedure"){
			if(q.FirstElementName != q.SecondElementName)
				for(int i=0;i<list.size();i++){
					if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
		}
		else if(q.FirstElementType == "Procedure"){
			if(q.SecondElementName == "_"){
				for(int i=0;i<list.size();i++){
					if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				int proc2Idx = procTable.getProIndex(q.SecondElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).second == proc2Idx){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		else if(q.SecondElementType == "Procedure"){
			if(q.FirstElementName == "_"){
				for(int i=0;i<list.size();i++){
					if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				int proc1Idx = procTable.getProIndex(q.FirstElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == proc1Idx){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_"){
				for(int i=0;i<list.size();i++){
					if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else if(q.FirstElementName == "_"){
				int proc2Idx = procTable.getProIndex(q.SecondElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).second == proc2Idx){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
			else if(q.SecondElementName == "_"){
				int proc1Idx = procTable.getProIndex(q.FirstElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == proc1Idx){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
			else{
				int procNum1 = procTable.getProIndex(q.FirstElementName), procNum2 = procTable.getProIndex(q.SecondElementName);
				if(calls.isCall(procNum1, procNum2)){
					if( find(tcol2.begin(), tcol2.end(), procNum2) != tcol2.end() ){
						col1.push_back(procNum1);
						col2.push_back(procNum2);
					}
				}
			}
		}
		break;
		   }
	case 3:{
		if(q.FirstElementType == "Procedure" && q.SecondElementType == "Procedure"){
			if(q.FirstElementName != q.SecondElementName)
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
		}
		else if(q.FirstElementType == "Procedure"){
			if(q.SecondElementName == "_"){
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				int proc2Idx = procTable.getProIndex(q.SecondElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).second == proc2Idx){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		else if(q.SecondElementType == "Procedure"){
			if(q.FirstElementName == "_"){
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				int proc1Idx = procTable.getProIndex(q.FirstElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == proc1Idx){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_"){
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else if(q.FirstElementName == "_"){
				int proc2Idx = procTable.getProIndex(q.SecondElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).second == proc2Idx){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
			else if(q.SecondElementName == "_"){
				int proc1Idx = procTable.getProIndex(q.FirstElementName);
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == proc1Idx){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
			else{
				int procNum1 = procTable.getProIndex(q.FirstElementName), procNum2 = procTable.getProIndex(q.SecondElementName);
				if(calls.isCall(procNum1, procNum2)){
					if( find(tcol1.begin(), tcol1.end(), procNum1) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), procNum2) != tcol2.end() ){
						col1.push_back(procNum1);
						col2.push_back(procNum2);
					}
				}
			}
		}
		break;
		   }
	}
	queryTree.at(index).table.push_back(col1);
	queryTree.at(index).table.push_back(col2);
}

void QueryProcessor::QueryNext(funcQuery_t q, int index, queryTreeNode_t finalTable){
	vector<int> col1, col2 , tcol1, tcol2;
	int colCase = 0;
	vector<string>::iterator it1 = find(finalTable.colName.begin(), finalTable.colName.end(), q.FirstElementName), 
		it2 = find(finalTable.colName.begin(), finalTable.colName.end(), q.SecondElementName);

	if(  it1 != finalTable.colName.end() ){
		colCase+=1;
		int pos = it1 - finalTable.colName.begin();
		tcol1 = finalTable.table.at(pos);
	}
	if(  it2 != finalTable.colName.end() ){
		colCase+=2;
		int pos = it2 - finalTable.colName.begin();
		tcol2 = finalTable.table.at(pos);
	}

	int totalLineNum = (*pkb).getTotalLineNum();
	vector<pair<int,int>> list = (*pkb).getNextList();
	vector<vector<int>> matrix = (*pkb).getNextMatrix();

	AST ast = (*pkb).getAST();

	switch(colCase){
	case 0:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				col1.push_back(c1);
				col2.push_back(c2);	
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						col1.push_back(c1);
						col2.push_back(i);
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						col1.push_back(c1);
						col2.push_back(i);
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						col1.push_back(i);
						col2.push_back(c2);
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						col1.push_back(i);
						col2.push_back(c2);
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementType != q.SecondElementName){
					for(int i=0;i<list.size();i++){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
				else{
					for(int i=0;i<list.size();i++){
						if(list.at(i).first == list.at(i).second){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName == q.SecondElementName){
					for(int i=0;i<list.size();i++)
						if(	list.at(i).first == list.at(i).second &&
							q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
						}
				}
				else{
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
						}
				}
			}
		}
		break;
		   }
	case 1:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find( tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
					col1.push_back(c1);
					col2.push_back(c2);
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find( tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find( tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
					for(int i=0;i<list.size();i++){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
				else{
					for(int i=0;i<list.size();i++){
						if(list.at(i).first == list.at(i).second){
							if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end()){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
					}
				}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName == q.SecondElementName){
					for(int i=0;i<list.size();i++)
						if(	list.at(i).first == list.at(i).second &&
							q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
				else{
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
			}
		}
		break;
		   }
	case 2:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find( tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
					col1.push_back(c1);
					col2.push_back(c2);
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find( tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find( tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
					for(int i=0;i<list.size();i++){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
				else{
					for(int i=0;i<list.size();i++){
						if(list.at(i).first == list.at(i).second){
							if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
					}
				}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName == q.SecondElementName){
					for(int i=0;i<list.size();i++)
						if(	list.at(i).first == list.at(i).second &&
							q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
				else{
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
			}
		}
		break;
		   }
	case 3:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
					find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
					col1.push_back(c1);
					col2.push_back(c2);
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
					for(int i=0;i<list.size();i++){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
				else{
					for(int i=0;i<list.size();i++){
						if(list.at(i).first == list.at(i).second){
							if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
								find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
					}
				}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName == q.SecondElementName){
					for(int i=0;i<list.size();i++)
						if(	list.at(i).first == list.at(i).second &&
							q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
									find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
				else{
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
									find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
			}
		}
		break;
		   }
	}
	queryTree.at(index).table.push_back(col1);
	queryTree.at(index).table.push_back(col2);
}

void QueryProcessor::QueryNextStar(funcQuery_t q, int index, queryTreeNode_t finalTable){
	vector<int> col1, col2 , tcol1, tcol2;
	int colCase = 0;
	vector<string>::iterator it1 = find(finalTable.colName.begin(), finalTable.colName.end(), q.FirstElementName), 
		it2 = find(finalTable.colName.begin(), finalTable.colName.end(), q.SecondElementName);

	if(  it1 != finalTable.colName.end() ){
		colCase+=1;
		int pos = it1 - finalTable.colName.begin();
		tcol1 = finalTable.table.at(pos);
	}
	if(  it2 != finalTable.colName.end() ){
		colCase+=2;
		int pos = it2 - finalTable.colName.begin();
		tcol2 = finalTable.table.at(pos);
	}

	int totalLineNum = (*pkb).getTotalLineNum();
	vector<pair<int,int>> list = (*pkb).getNextStarList();
	vector<vector<int>> matrix = (*pkb).getNextStarMatrix();

	AST ast = (*pkb).getAST();

	switch(colCase){
	case 0:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				col1.push_back(c1);
				col2.push_back(c2);	
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						col1.push_back(c1);
						col2.push_back(i);
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						col1.push_back(c1);
						col2.push_back(i);
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						col1.push_back(i);
						col2.push_back(c2);
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						col1.push_back(i);
						col2.push_back(c2);
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementType != q.SecondElementName){
					for(int i=0;i<list.size();i++){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
				else{
					for(int i=0;i<list.size();i++){
						if(list.at(i).first == list.at(i).second){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName == q.SecondElementName){
					for(int i=0;i<list.size();i++)
						if(	list.at(i).first == list.at(i).second &&
							q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
						}
				}
				else{
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
						}
				}
			}
		}
		break;
		   }
	case 1:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find( tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
					col1.push_back(c1);
					col2.push_back(c2);
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find( tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find( tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
					for(int i=0;i<list.size();i++){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
				else{
					for(int i=0;i<list.size();i++){
						if(list.at(i).first == list.at(i).second){
							if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end()){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
					}
				}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName == q.SecondElementName){
					for(int i=0;i<list.size();i++)
						if(	list.at(i).first == list.at(i).second &&
							q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
				else{
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
			}
		}
		break;
		   }
	case 2:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find( tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
					col1.push_back(c1);
					col2.push_back(c2);
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find( tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find( tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
					for(int i=0;i<list.size();i++){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
				else{
					for(int i=0;i<list.size();i++){
						if(list.at(i).first == list.at(i).second){
							if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
					}
				}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName == q.SecondElementName){
					for(int i=0;i<list.size();i++)
						if(	list.at(i).first == list.at(i).second &&
							q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
				else{
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
			}
		}
		break;
		   }
	case 3:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
					find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
					col1.push_back(c1);
					col2.push_back(c2);
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
					for(int i=0;i<list.size();i++){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
				else{
					for(int i=0;i<list.size();i++){
						if(list.at(i).first == list.at(i).second){
							if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
								find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
					}
				}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName == q.SecondElementName){
					for(int i=0;i<list.size();i++)
						if(	list.at(i).first == list.at(i).second &&
							q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
									find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
				else{
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
									find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
			}
		}
		break;
		   }
	}
	queryTree.at(index).table.push_back(col1);
	queryTree.at(index).table.push_back(col2);
}

void QueryProcessor::QueryNextBip(funcQuery_t q, int index, queryTreeNode_t finalTable){
	vector<int> col1, col2 , tcol1, tcol2;
	int colCase = 0;
	vector<string>::iterator it1 = find(finalTable.colName.begin(), finalTable.colName.end(), q.FirstElementName), 
		it2 = find(finalTable.colName.begin(), finalTable.colName.end(), q.SecondElementName);

	if(  it1 != finalTable.colName.end() ){
		colCase+=1;
		int pos = it1 - finalTable.colName.begin();
		tcol1 = finalTable.table.at(pos);
	}
	if(  it2 != finalTable.colName.end() ){
		colCase+=2;
		int pos = it2 - finalTable.colName.begin();
		tcol2 = finalTable.table.at(pos);
	}

	int totalLineNum = (*pkb).getTotalLineNum();
	vector<pair<int,int>> list = (*pkb).getNextBipList();
	vector<vector<int>> matrix = (*pkb).getNextBipMatrix();

	AST ast = (*pkb).getAST();

	switch(colCase){
	case 0:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				col1.push_back(c1);
				col2.push_back(c2);	
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						col1.push_back(c1);
						col2.push_back(i);
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						col1.push_back(c1);
						col2.push_back(i);
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						col1.push_back(i);
						col2.push_back(c2);
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						col1.push_back(i);
						col2.push_back(c2);
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementType != q.SecondElementName){
					for(int i=0;i<list.size();i++){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
				else{
					for(int i=0;i<list.size();i++){
						if(list.at(i).first == list.at(i).second){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName == q.SecondElementName){
					for(int i=0;i<list.size();i++)
						if(	list.at(i).first == list.at(i).second &&
							q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
						}
				}
				else{
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
						}
				}
			}
		}
		break;
		   }
	case 1:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find( tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
					col1.push_back(c1);
					col2.push_back(c2);
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find( tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find( tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
					for(int i=0;i<list.size();i++){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
				else{
					for(int i=0;i<list.size();i++){
						if(list.at(i).first == list.at(i).second){
							if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end()){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
					}
				}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName == q.SecondElementName){
					for(int i=0;i<list.size();i++)
						if(	list.at(i).first == list.at(i).second &&
							q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
				else{
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
			}
		}
		break;
		   }
	case 2:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find( tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
					col1.push_back(c1);
					col2.push_back(c2);
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find( tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find( tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
					for(int i=0;i<list.size();i++){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
				else{
					for(int i=0;i<list.size();i++){
						if(list.at(i).first == list.at(i).second){
							if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
					}
				}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName == q.SecondElementName){
					for(int i=0;i<list.size();i++)
						if(	list.at(i).first == list.at(i).second &&
							q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
				else{
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
			}
		}
		break;
		   }
	case 3:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
					find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
					col1.push_back(c1);
					col2.push_back(c2);
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
					for(int i=0;i<list.size();i++){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
				else{
					for(int i=0;i<list.size();i++){
						if(list.at(i).first == list.at(i).second){
							if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
								find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
					}
				}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName == q.SecondElementName){
					for(int i=0;i<list.size();i++)
						if(	list.at(i).first == list.at(i).second &&
							q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
									find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
				else{
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
									find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
			}
		}
		break;
		   }
	}
	queryTree.at(index).table.push_back(col1);
	queryTree.at(index).table.push_back(col2);
}

void QueryProcessor::QueryNextBipStar(funcQuery_t q, int index, queryTreeNode_t finalTable){
	vector<int> col1, col2 , tcol1, tcol2;
	int colCase = 0;
	vector<string>::iterator it1 = find(finalTable.colName.begin(), finalTable.colName.end(), q.FirstElementName), 
		it2 = find(finalTable.colName.begin(), finalTable.colName.end(), q.SecondElementName);

	if(  it1 != finalTable.colName.end() ){
		colCase+=1;
		int pos = it1 - finalTable.colName.begin();
		tcol1 = finalTable.table.at(pos);
	}
	if(  it2 != finalTable.colName.end() ){
		colCase+=2;
		int pos = it2 - finalTable.colName.begin();
		tcol2 = finalTable.table.at(pos);
	}

	int totalLineNum = (*pkb).getTotalLineNum();
	vector<pair<int,int>> list = (*pkb).getNextBipStarList();
	vector<vector<int>> matrix = (*pkb).getNextBipStarMatrix();

	AST ast = (*pkb).getAST();

	switch(colCase){
	case 0:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				col1.push_back(c1);
				col2.push_back(c2);	
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						col1.push_back(c1);
						col2.push_back(i);
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						col1.push_back(c1);
						col2.push_back(i);
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						col1.push_back(i);
						col2.push_back(c2);
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						col1.push_back(i);
						col2.push_back(c2);
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementType != q.SecondElementName){
					for(int i=0;i<list.size();i++){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
				else{
					for(int i=0;i<list.size();i++){
						if(list.at(i).first == list.at(i).second){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName == q.SecondElementName){
					for(int i=0;i<list.size();i++)
						if(	list.at(i).first == list.at(i).second &&
							q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
						}
				}
				else{
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
						}
				}
			}
		}
		break;
		   }
	case 1:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find( tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
					col1.push_back(c1);
					col2.push_back(c2);
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find( tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find( tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
					for(int i=0;i<list.size();i++){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
				else{
					for(int i=0;i<list.size();i++){
						if(list.at(i).first == list.at(i).second){
							if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end()){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
					}
				}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName == q.SecondElementName){
					for(int i=0;i<list.size();i++)
						if(	list.at(i).first == list.at(i).second &&
							q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
				else{
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
			}
		}
		break;
		   }
	case 2:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find( tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
					col1.push_back(c1);
					col2.push_back(c2);
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find( tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find( tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
					for(int i=0;i<list.size();i++){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
				else{
					for(int i=0;i<list.size();i++){
						if(list.at(i).first == list.at(i).second){
							if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
					}
				}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName == q.SecondElementName){
					for(int i=0;i<list.size();i++)
						if(	list.at(i).first == list.at(i).second &&
							q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
				else{
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
			}
		}
		break;
		   }
	case 3:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
					find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
					col1.push_back(c1);
					col2.push_back(c2);
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.SecondElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(c1).at(i) == 1 && q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
							col1.push_back(c1);
							col2.push_back(i);
						}
					}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(q.FirstElementType.compare("Statement") == 0){
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
			else{
				for(int i=1;i<=totalLineNum;i++)
					if(matrix.at(i).at(c2) == 1 && q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), i)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), c2) != tcol2.end()){
							col1.push_back(i);
							col2.push_back(c2);
						}
					}
			}
		}
		// Both arg are not constant.
		else{
			// Both arg are of statement type.
			if(q.FirstElementType.compare("Statement") == 0 && q.SecondElementType.compare("Statement") == 0){
				if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
					for(int i=0;i<list.size();i++){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
				else{
					for(int i=0;i<list.size();i++){
						if(list.at(i).first == list.at(i).second){
							if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
								find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
								col1.push_back(list.at(i).first);
								col2.push_back(list.at(i).second);
							}
						}
					}
				}
			}
			// First arg is of statement type.
			else if(q.FirstElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Second arg is of statemnt type.
			else if(q.SecondElementType.compare("Statement") == 0){
				for(int i=0;i<list.size();i++)
					if(q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType()){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
			}
			// Both args are not of the type statement.
			else{
				if(q.FirstElementName == q.SecondElementName){
					for(int i=0;i<list.size();i++)
						if(	list.at(i).first == list.at(i).second &&
							q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
									find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
				else{
					for(int i=0;i<list.size();i++)
						if(	q.FirstElementType == (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).first)).getNodeType() && 
							q.SecondElementType== (*ast.getNodeFromLineNum(ast.getRoot(), list.at(i).second)).getNodeType()){
								if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
									find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
									col1.push_back(list.at(i).first);
									col2.push_back(list.at(i).second);
								}
						}
				}
			}
		}
		break;
		   }
	}
	queryTree.at(index).table.push_back(col1);
	queryTree.at(index).table.push_back(col2);
}

void QueryProcessor::QueryAffects(funcQuery_t q, int index, queryTreeNode_t finalTable){
	vector<int> col1, col2 , tcol1, tcol2;
	int colCase = 0;
	vector<string>::iterator it1 = find(finalTable.colName.begin(), finalTable.colName.end(), q.FirstElementName), 
		it2 = find(finalTable.colName.begin(), finalTable.colName.end(), q.SecondElementName);

	if(  it1 != finalTable.colName.end() ){
		colCase+=1;
		int pos = it1 - finalTable.colName.begin();
		tcol1 = finalTable.table.at(pos);
	}
	if(  it2 != finalTable.colName.end() ){
		colCase+=2;
		int pos = it2 - finalTable.colName.begin();
		tcol2 = finalTable.table.at(pos);
	}

	int totalLineNum = (*pkb).getTotalLineNum();
	StmtTable st = (*pkb).getStmtTable();

	vector<pair<int,int>> list = (*pkb).getAffectsList();
	vector<vector<int>> matrix = (*pkb).getAffectsMatrix();


	switch(colCase){
	case 0:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign" || st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				col1.push_back(c1);
				col2.push_back(c2);	
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(c1).at(i) == 1){
					col1.push_back(c1);
					col2.push_back(i);
				}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(i).at(c2) == 1){
					col1.push_back(i);
					col2.push_back(c2);
				}
			}
		}
		// Both arg are not constant.
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
				for(int i=0;i<list.size();i++){
					col1.push_back(list.at(i).first);
					col2.push_back(list.at(i).second);
				}
			}
			else{
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == list.at(i).second){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
		}
		break;
		   }
	case 1:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign" || st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
					col1.push_back(c1);
					col2.push_back(c2);	
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(c1).at(i) == 1){
					if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
						col1.push_back(c1);
						col2.push_back(i);
					}
				}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(i).at(c2) == 1){
					if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() ){
						col1.push_back(i);
						col2.push_back(c2);
					}
				}
			}
		}
		// Both arg are not constant.
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == list.at(i).second){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		break;
		   }
	case 2:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign" || st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
					col1.push_back(c1);
					col2.push_back(c2);	
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(c1).at(i) == 1){
					if( find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
						col1.push_back(c1);
						col2.push_back(i);
					}
				}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(i).at(c2) == 1){
					if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
						col1.push_back(i);
						col2.push_back(c2);
					}
				}
			}
		}
		// Both arg are not constant.
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
				for(int i=0;i<list.size();i++){
					if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == list.at(i).second){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		break;
		   }
	case 3:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign" || st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
					find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
					col1.push_back(c1);
					col2.push_back(c2);	
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(c1).at(i) == 1){
					if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
						col1.push_back(c1);
						col2.push_back(i);
					}
				}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(i).at(c2) == 1){
					if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
						col1.push_back(i);
						col2.push_back(c2);
					}
				}
			}
		}
		// Both arg are not constant.
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == list.at(i).second){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		break;
		   }
	}

	queryTree.at(index).table.push_back(col1);
	queryTree.at(index).table.push_back(col2);
}

void QueryProcessor::QueryAffectsStar(funcQuery_t q, int index, queryTreeNode_t finalTable){
	vector<int> col1, col2 , tcol1, tcol2;
	int colCase = 0;
	vector<string>::iterator it1 = find(finalTable.colName.begin(), finalTable.colName.end(), q.FirstElementName), 
		it2 = find(finalTable.colName.begin(), finalTable.colName.end(), q.SecondElementName);

	if(  it1 != finalTable.colName.end() ){
		colCase+=1;
		int pos = it1 - finalTable.colName.begin();
		tcol1 = finalTable.table.at(pos);
	}
	if(  it2 != finalTable.colName.end() ){
		colCase+=2;
		int pos = it2 - finalTable.colName.begin();
		tcol2 = finalTable.table.at(pos);
	}

	int totalLineNum = (*pkb).getTotalLineNum();
	StmtTable st = (*pkb).getStmtTable();

	vector<pair<int,int>> list = (*pkb).getAffectsStarList();
	vector<vector<int>> matrix = (*pkb).getAffectsStarMatrix();


	switch(colCase){
	case 0:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign" || st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				col1.push_back(c1);
				col2.push_back(c2);	
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(c1).at(i) == 1){
					col1.push_back(c1);
					col2.push_back(i);
				}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(i).at(c2) == 1){
					col1.push_back(i);
					col2.push_back(c2);
				}
			}
		}
		// Both arg are not constant.
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
				for(int i=0;i<list.size();i++){
					col1.push_back(list.at(i).first);
					col2.push_back(list.at(i).second);
				}
			}
			else{
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == list.at(i).second){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
		}
		break;
		   }
	case 1:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign" || st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
					col1.push_back(c1);
					col2.push_back(c2);	
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(c1).at(i) == 1){
					if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
						col1.push_back(c1);
						col2.push_back(i);
					}
				}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(i).at(c2) == 1){
					if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() ){
						col1.push_back(i);
						col2.push_back(c2);
					}
				}
			}
		}
		// Both arg are not constant.
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == list.at(i).second){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		break;
		   }
	case 2:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign" || st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
					col1.push_back(c1);
					col2.push_back(c2);	
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(c1).at(i) == 1){
					if( find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
						col1.push_back(c1);
						col2.push_back(i);
					}
				}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(i).at(c2) == 1){
					if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
						col1.push_back(i);
						col2.push_back(c2);
					}
				}
			}
		}
		// Both arg are not constant.
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
				for(int i=0;i<list.size();i++){
					if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == list.at(i).second){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		break;
		   }
	case 3:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign" || st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
					find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
					col1.push_back(c1);
					col2.push_back(c2);	
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(c1).at(i) == 1){
					if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
						col1.push_back(c1);
						col2.push_back(i);
					}
				}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(i).at(c2) == 1){
					if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
						col1.push_back(i);
						col2.push_back(c2);
					}
				}
			}
		}
		// Both arg are not constant.
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == list.at(i).second){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		break;
		   }
	}

	queryTree.at(index).table.push_back(col1);
	queryTree.at(index).table.push_back(col2);
}

void QueryProcessor::QueryAffectsBip(funcQuery_t q, int index, queryTreeNode_t finalTable){
	vector<int> col1, col2 , tcol1, tcol2;
	int colCase = 0;
	vector<string>::iterator it1 = find(finalTable.colName.begin(), finalTable.colName.end(), q.FirstElementName), 
		it2 = find(finalTable.colName.begin(), finalTable.colName.end(), q.SecondElementName);

	if(  it1 != finalTable.colName.end() ){
		colCase+=1;
		int pos = it1 - finalTable.colName.begin();
		tcol1 = finalTable.table.at(pos);
	}
	if(  it2 != finalTable.colName.end() ){
		colCase+=2;
		int pos = it2 - finalTable.colName.begin();
		tcol2 = finalTable.table.at(pos);
	}

	int totalLineNum = (*pkb).getTotalLineNum();
	StmtTable st = (*pkb).getStmtTable();

	vector<pair<int,int>> list = affectsBip.GetAffectsBipList();
	vector<vector<int>> matrix = affectsBip.GetAffectsBipMatrix();


	switch(colCase){
	case 0:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign" || st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				col1.push_back(c1);
				col2.push_back(c2);	
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(c1).at(i) == 1){
					col1.push_back(c1);
					col2.push_back(i);
				}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(i).at(c2) == 1){
					col1.push_back(i);
					col2.push_back(c2);
				}
			}
		}
		// Both arg are not constant.
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
				for(int i=0;i<list.size();i++){
					col1.push_back(list.at(i).first);
					col2.push_back(list.at(i).second);
				}
			}
			else{
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == list.at(i).second){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
		}
		break;
		   }
	case 1:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign" || st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
					col1.push_back(c1);
					col2.push_back(c2);	
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(c1).at(i) == 1){
					if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
						col1.push_back(c1);
						col2.push_back(i);
					}
				}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(i).at(c2) == 1){
					if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() ){
						col1.push_back(i);
						col2.push_back(c2);
					}
				}
			}
		}
		// Both arg are not constant.
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == list.at(i).second){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		break;
		   }
	case 2:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign" || st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
					col1.push_back(c1);
					col2.push_back(c2);	
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(c1).at(i) == 1){
					if( find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
						col1.push_back(c1);
						col2.push_back(i);
					}
				}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(i).at(c2) == 1){
					if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
						col1.push_back(i);
						col2.push_back(c2);
					}
				}
			}
		}
		// Both arg are not constant.
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
				for(int i=0;i<list.size();i++){
					if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == list.at(i).second){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		break;
		   }
	case 3:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign" || st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
					find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
					col1.push_back(c1);
					col2.push_back(c2);	
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(c1).at(i) == 1){
					if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
						col1.push_back(c1);
						col2.push_back(i);
					}
				}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(i).at(c2) == 1){
					if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
						col1.push_back(i);
						col2.push_back(c2);
					}
				}
			}
		}
		// Both arg are not constant.
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == list.at(i).second){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		break;
		   }
	}

	queryTree.at(index).table.push_back(col1);
	queryTree.at(index).table.push_back(col2);
}

void QueryProcessor::QueryAffectsBipStar(funcQuery_t q, int index, queryTreeNode_t finalTable){
	vector<int> col1, col2 , tcol1, tcol2;
	int colCase = 0;
	vector<string>::iterator it1 = find(finalTable.colName.begin(), finalTable.colName.end(), q.FirstElementName), 
		it2 = find(finalTable.colName.begin(), finalTable.colName.end(), q.SecondElementName);

	if(  it1 != finalTable.colName.end() ){
		colCase+=1;
		int pos = it1 - finalTable.colName.begin();
		tcol1 = finalTable.table.at(pos);
	}
	if(  it2 != finalTable.colName.end() ){
		colCase+=2;
		int pos = it2 - finalTable.colName.begin();
		tcol2 = finalTable.table.at(pos);
	}

	int totalLineNum = (*pkb).getTotalLineNum();
	StmtTable st = (*pkb).getStmtTable();

	vector<pair<int,int>> list = affectsBip.GetAffectsBipStarList();
	vector<vector<int>> matrix = affectsBip.GetAffectsBipStarMatrix();


	switch(colCase){
	case 0:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign" || st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				col1.push_back(c1);
				col2.push_back(c2);	
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(c1).at(i) == 1){
					col1.push_back(c1);
					col2.push_back(i);
				}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(i).at(c2) == 1){
					col1.push_back(i);
					col2.push_back(c2);
				}
			}
		}
		// Both arg are not constant.
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
				for(int i=0;i<list.size();i++){
					col1.push_back(list.at(i).first);
					col2.push_back(list.at(i).second);
				}
			}
			else{
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == list.at(i).second){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
		}
		break;
		   }
	case 1:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign" || st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
					col1.push_back(c1);
					col2.push_back(c2);	
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(c1).at(i) == 1){
					if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() ){
						col1.push_back(c1);
						col2.push_back(i);
					}
				}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(i).at(c2) == 1){
					if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() ){
						col1.push_back(i);
						col2.push_back(c2);
					}
				}
			}
		}
		// Both arg are not constant.
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == list.at(i).second){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		break;
		   }
	case 2:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign" || st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
					col1.push_back(c1);
					col2.push_back(c2);	
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(c1).at(i) == 1){
					if( find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
						col1.push_back(c1);
						col2.push_back(i);
					}
				}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(i).at(c2) == 1){
					if( find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
						col1.push_back(i);
						col2.push_back(c2);
					}
				}
			}
		}
		// Both arg are not constant.
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
				for(int i=0;i<list.size();i++){
					if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == list.at(i).second){
						if( find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		break;
		   }
	case 3:{
		// Both args are constant.
		if(q.FirstElementType.compare("Constant") == 0 && q.SecondElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str()), c2 = atoi(q.SecondElementName.c_str());
			if(c1>totalLineNum || c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign" || st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			if(matrix.at(c1).at(c2) == 1){
				if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
					find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
					col1.push_back(c1);
					col2.push_back(c2);	
				}
			}
		}
		// First arg is constant.
		else if(q.FirstElementType.compare("Constant") == 0){
			int c1 = atoi(q.FirstElementName.c_str());
			if(c1>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c1).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(c1).at(i) == 1){
					if( find(tcol1.begin(), tcol1.end(), c1) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), i) != tcol2.end() ){
						col1.push_back(c1);
						col2.push_back(i);
					}
				}
			}
		}
		// Second arg is constant.
		else if(q.SecondElementType.compare("Constant") == 0){
			int c2 = atoi(q.SecondElementName.c_str());
			if(c2>totalLineNum){
				queryTree.at(index).table.push_back(col1);
				queryTree.at(index).table.push_back(col2);
				return;
			}
			if(st.getLineDetails(c2).type != "Assign"){
				throw exception("Affects need query on Assignments.");
				return;
			}
			for(int i=1;i<=totalLineNum;i++){
				if(matrix.at(i).at(c2) == 1){
					if( find(tcol1.begin(), tcol1.end(), i) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), c2) != tcol2.end() ){
						col1.push_back(i);
						col2.push_back(c2);
					}
				}
			}
		}
		// Both arg are not constant.
		else{
			if(q.FirstElementName == "_" && q.SecondElementName == "_" || q.FirstElementName != q.SecondElementName){
				for(int i=0;i<list.size();i++){
					if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
						find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
						col1.push_back(list.at(i).first);
						col2.push_back(list.at(i).second);
					}
				}
			}
			else{
				for(int i=0;i<list.size();i++){
					if(list.at(i).first == list.at(i).second){
						if( find(tcol1.begin(), tcol1.end(), list.at(i).first) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), list.at(i).second) != tcol2.end() ){
							col1.push_back(list.at(i).first);
							col2.push_back(list.at(i).second);
						}
					}
				}
			}
		}
		break;
		   }
	}

	queryTree.at(index).table.push_back(col1);
	queryTree.at(index).table.push_back(col2);
}

void QueryProcessor::QueryPattern(patternQuery_t q, int index, queryTreeNode_t finalTable){
	vector<Pattern> pt = (*pkb).getPatternTable().getPatternTable();
	VarTable varTable = (*pkb).getVarTable();
	// 1st arg is variable reference
	if(!q.isVarRefVariable){
		vector<int> col, tcol;
		vector<string>::iterator it = find(finalTable.colName.begin(), finalTable.colName.end(), q.ElementName);
		bool colFound = false;
		if(  it != finalTable.colName.end() ){
			colFound = true;
			int pos = it - finalTable.colName.begin();
			tcol = finalTable.table.at(pos);
		}
		if(!colFound){
			// Assign Pattern
			if(q.ElementType == "Assign"){
				// Pattern a (_,*)
				if(q.VarRef == "_"){
					// a(_,_)
					if(q.Expression.empty() || q.Expression.size() == 0){
						for(int i=0;i<pt.size();i++)
							if(pt.at(i).getType() == 0)
								col.push_back(pt.at(i).getLineNum());
					}
					// a(_,exp)
					else if(!q.ExpWithUnderscore){
						for(int i=0;i<pt.size();i++){
							if(pt.at(i).getType() == 0 && areIdentical(q.Expression, 0,pt.at(i).getNodeTree(),0))
								col.push_back(pt.at(i).getLineNum());
						}
					}
					// a(_,_exp_)
					else{
						for(int i=0;i<pt.size();i++){
							if(pt.at(i).getType() == 0 && isSubtree(q.Expression,0, pt.at(i).getNodeTree(),0))
								col.push_back(pt.at(i).getLineNum());
						}
					}
				}
				// Pattern a("",*)
				else{
					// a("",_)
					if(q.Expression.empty() || q.Expression.size() == 0){
						for(int i=0;i<pt.size();i++)
							if(pt.at(i).getType() == 0 && pt.at(i).getVarName() == q.VarRef)
								col.push_back(pt.at(i).getLineNum());
					}
					// a("",exp)
					else if(!q.ExpWithUnderscore){
						for(int i=0;i<pt.size();i++){
							if(pt.at(i).getType() == 0 && q.VarRef == pt.at(i).getVarName() && areIdentical(q.Expression,0, pt.at(i).getNodeTree(),0))
								col.push_back(pt.at(i).getLineNum());
						}
					}
					// a("",_exp_)
					else{
						for(int i=0;i<pt.size();i++){
							if(pt.at(i).getType() == 0 && q.VarRef == pt.at(i).getVarName() && isSubtree(q.Expression, 0,pt.at(i).getNodeTree(),0))
								col.push_back(pt.at(i).getLineNum());
						}
					}
				}
			}
			// Pattern while|if
			else{
				for(int i=0;i<pt.size();i++)
					if(	patternType.at(pt.at(i).getType()) == q.ElementType && 
						(q.VarRef == "_" || q.VarRef == pt.at(i).getVarName()) )
						col.push_back(pt.at(i).getLineNum());
			}
		}
		else{
			// Assign Pattern
			if(q.ElementType == "Assign"){
				// Pattern a (_,*)
				if(q.VarRef == "_"){
					// a(_,_)
					if(q.Expression.empty() || q.Expression.size() == 0){
						for(int i=0;i<pt.size();i++)
							if(pt.at(i).getType() == 0)
								if( find(tcol.begin(), tcol.end(), pt.at(i).getLineNum()) != tcol.end())
									col.push_back(pt.at(i).getLineNum());
					}
					// a(_,exp)
					else if(!q.ExpWithUnderscore){
						for(int i=0;i<pt.size();i++){
							if(pt.at(i).getType() == 0 && areIdentical(q.Expression, 0,pt.at(i).getNodeTree(),0))
								if( find(tcol.begin(), tcol.end(), pt.at(i).getLineNum()) != tcol.end())
									col.push_back(pt.at(i).getLineNum());
						}
					}
					// a(_,_exp_)
					else{
						for(int i=0;i<pt.size();i++){
							if(pt.at(i).getType() == 0 && isSubtree(q.Expression,0, pt.at(i).getNodeTree(),0))
								if( find(tcol.begin(), tcol.end(), pt.at(i).getLineNum()) != tcol.end())
									col.push_back(pt.at(i).getLineNum());
						}
					}
				}
				// Pattern a("",*)
				else{
					// a("",_)
					if(q.Expression.empty() || q.Expression.size() == 0){
						for(int i=0;i<pt.size();i++)
							if(pt.at(i).getType() == 0 && pt.at(i).getVarName() == q.VarRef)
								if( find(tcol.begin(), tcol.end(), pt.at(i).getLineNum()) != tcol.end())
									col.push_back(pt.at(i).getLineNum());
					}
					// a("",exp)
					else if(!q.ExpWithUnderscore){
						for(int i=0;i<pt.size();i++){
							if(pt.at(i).getType() == 0 && q.VarRef == pt.at(i).getVarName() && areIdentical(q.Expression,0, pt.at(i).getNodeTree(),0))
								if( find(tcol.begin(), tcol.end(), pt.at(i).getLineNum()) != tcol.end())
									col.push_back(pt.at(i).getLineNum());
						}
					}
					// a("",_exp_)
					else{
						for(int i=0;i<pt.size();i++){
							if(pt.at(i).getType() == 0 && q.VarRef == pt.at(i).getVarName() && isSubtree(q.Expression, 0,pt.at(i).getNodeTree(),0))
								if( find(tcol.begin(), tcol.end(), pt.at(i).getLineNum()) != tcol.end())
									col.push_back(pt.at(i).getLineNum());
						}
					}
				}
			}
			// Pattern while|if
			else{
				for(int i=0;i<pt.size();i++)
					if(	patternType.at(pt.at(i).getType()) == q.ElementType && 
						( q.VarRef == "_" || q.VarRef == pt.at(i).getVarName()) )
						if( find(tcol.begin(), tcol.end(), pt.at(i).getLineNum()) != tcol.end())
							col.push_back(pt.at(i).getLineNum());
			}
		}
		queryTree.at(index).table.push_back(col);
	}


	// 1st arg not variable reference
	else{
		vector<int> col1, col2 , tcol1, tcol2;
		int colCase = 0;
		vector<string>::iterator it1 = find(finalTable.colName.begin(), finalTable.colName.end(), q.ElementName), 
			it2 = find(finalTable.colName.begin(), finalTable.colName.end(), q.VarRef);

		if(  it1 != finalTable.colName.end() ){
			colCase+=1;
			int pos = it1 - finalTable.colName.begin();
			tcol1 = finalTable.table.at(pos);
		}
		if(  it2 != finalTable.colName.end() ){
			colCase+=2;
			int pos = it2 - finalTable.colName.begin();
			tcol2 = finalTable.table.at(pos);
		}

		switch(colCase){
		case 0:{
			// Assign
			if(q.ElementType == "Assign"){
				// Pattern a (v,*)
				// a(v,_)
				if(q.Expression.empty() || q.Expression.size() == 0){
					for(int i=0;i<pt.size();i++)
						if(pt.at(i).getType() == 0){
							col1.push_back(pt.at(i).getLineNum());
							col2.push_back(varTable.getVarIndex(pt.at(i).getVarName()));
						}
				}
				// a(v,exp)
				else if(!q.ExpWithUnderscore){
					for(int i=0;i<pt.size();i++){
						if(pt.at(i).getType() == 0 && areIdentical(q.Expression, 0,pt.at(i).getNodeTree(),0)){
							col1.push_back(pt.at(i).getLineNum());
							col2.push_back(varTable.getVarIndex(pt.at(i).getVarName()));
						}
					}
				}
				// a(v,_exp_)
				else{
					for(int i=0;i<pt.size();i++){
						if(pt.at(i).getType() == 0 && isSubtree(q.Expression,0, pt.at(i).getNodeTree(),0)){
							col1.push_back(pt.at(i).getLineNum());
							col2.push_back(varTable.getVarIndex(pt.at(i).getVarName()));
						}
					}
				}
			}
			// While/If
			else{
				for(int i=0;i<pt.size();i++)
					if(patternType.at(pt.at(i).getType()) == q.ElementType){
						col1.push_back(pt.at(i).getLineNum());
						col2.push_back(varTable.getVarIndex(pt.at(i).getVarName()));
					}
			}
			break;
			   }
		case 1:{
			// Assign
			if(q.ElementType == "Assign"){
				// Pattern a (v,*)
				// a(v,_)
				if(q.Expression.empty() || q.Expression.size() == 0){
					for(int i=0;i<pt.size();i++)
						if(pt.at(i).getType() == 0){
							if( find(tcol1.begin(), tcol1.end(), pt.at(i).getLineNum()) != tcol1.end() ){
								col1.push_back(pt.at(i).getLineNum());
								col2.push_back(varTable.getVarIndex(pt.at(i).getVarName()));
							}
						}
				}
				// a(v,exp)
				else if(!q.ExpWithUnderscore){
					for(int i=0;i<pt.size();i++){
						if(pt.at(i).getType() == 0 && areIdentical(q.Expression, 0,pt.at(i).getNodeTree(),0)){
							if( find(tcol1.begin(), tcol1.end(), pt.at(i).getLineNum()) != tcol1.end() ){
								col1.push_back(pt.at(i).getLineNum());
								col2.push_back(varTable.getVarIndex(pt.at(i).getVarName()));
							}
						}
					}
				}
				// a(v,_exp_)
				else{
					for(int i=0;i<pt.size();i++){
						if(pt.at(i).getType() == 0 && isSubtree(q.Expression,0, pt.at(i).getNodeTree(),0)){
							if( find(tcol1.begin(), tcol1.end(), pt.at(i).getLineNum()) != tcol1.end() ){
								col1.push_back(pt.at(i).getLineNum());
								col2.push_back(varTable.getVarIndex(pt.at(i).getVarName()));
							}
						}
					}
				}
			}
			// While/If
			else{
				for(int i=0;i<pt.size();i++)
					if(patternType.at(pt.at(i).getType()) == q.ElementType){
						if( find(tcol1.begin(), tcol1.end(), pt.at(i).getLineNum()) != tcol1.end() ){
							col1.push_back(pt.at(i).getLineNum());
							col2.push_back(varTable.getVarIndex(pt.at(i).getVarName()));
						}
					}
			}
			break;
			   }
		case 2:{
			// Assign
			if(q.ElementType == "Assign"){
				// Pattern a (v,*)
				// a(v,_)
				if(q.Expression.empty() || q.Expression.size() == 0){
					for(int i=0;i<pt.size();i++)
						if(pt.at(i).getType() == 0){
							if( find(tcol2.begin(), tcol2.end(), varTable.getVarIndex(pt.at(i).getVarName())) != tcol2.end() ){
								col1.push_back(pt.at(i).getLineNum());
								col2.push_back(varTable.getVarIndex(pt.at(i).getVarName()));
							}
						}
				}
				// a(v,exp)
				else if(!q.ExpWithUnderscore){
					for(int i=0;i<pt.size();i++){
						if(pt.at(i).getType() == 0 && areIdentical(q.Expression, 0,pt.at(i).getNodeTree(),0)){
							if( find(tcol2.begin(), tcol2.end(), varTable.getVarIndex(pt.at(i).getVarName())) != tcol2.end() ){
								col1.push_back(pt.at(i).getLineNum());
								col2.push_back(varTable.getVarIndex(pt.at(i).getVarName()));
							}
						}
					}
				}
				// a(v,_exp_)
				else{
					for(int i=0;i<pt.size();i++){
						if(pt.at(i).getType() == 0 && isSubtree(q.Expression,0, pt.at(i).getNodeTree(),0)){
							if( find(tcol2.begin(), tcol2.end(), varTable.getVarIndex(pt.at(i).getVarName())) != tcol2.end() ){
								col1.push_back(pt.at(i).getLineNum());
								col2.push_back(varTable.getVarIndex(pt.at(i).getVarName()));
							}
						}
					}
				}
			}
			// While/If
			else{
				for(int i=0;i<pt.size();i++)
					if(patternType.at(pt.at(i).getType()) == q.ElementType){
						if( find(tcol2.begin(), tcol2.end(), varTable.getVarIndex(pt.at(i).getVarName())) != tcol2.end() ){
							col1.push_back(pt.at(i).getLineNum());
							col2.push_back(varTable.getVarIndex(pt.at(i).getVarName()));
						}
					}
			}
			break;
			   }
		case 3:{
			// Assign
			if(q.ElementType == "Assign"){
				// Pattern a (v,*)
				// a(v,_)
				if(q.Expression.empty() || q.Expression.size() == 0){
					for(int i=0;i<pt.size();i++)
						if(pt.at(i).getType() == 0){
							if( find(tcol1.begin(), tcol1.end(), pt.at(i).getLineNum()) != tcol1.end() &&
								find(tcol2.begin(), tcol2.end(), varTable.getVarIndex(pt.at(i).getVarName())) != tcol2.end() ){
								col1.push_back(pt.at(i).getLineNum());
								col2.push_back(varTable.getVarIndex(pt.at(i).getVarName()));
							}
						}
				}
				// a(v,exp)
				else if(!q.ExpWithUnderscore){
					for(int i=0;i<pt.size();i++){
						if(pt.at(i).getType() == 0 && areIdentical(q.Expression, 0,pt.at(i).getNodeTree(),0)){
							if( find(tcol1.begin(), tcol1.end(), pt.at(i).getLineNum()) != tcol1.end() &&
								find(tcol2.begin(), tcol2.end(), varTable.getVarIndex(pt.at(i).getVarName())) != tcol2.end() ){
								col1.push_back(pt.at(i).getLineNum());
								col2.push_back(varTable.getVarIndex(pt.at(i).getVarName()));
							}
						}
					}
				}
				// a(v,_exp_)
				else{
					for(int i=0;i<pt.size();i++){
						if(pt.at(i).getType() == 0 && isSubtree(q.Expression,0, pt.at(i).getNodeTree(),0)){
							if( find(tcol1.begin(), tcol1.end(), pt.at(i).getLineNum()) != tcol1.end() &&
								find(tcol2.begin(), tcol2.end(), varTable.getVarIndex(pt.at(i).getVarName())) != tcol2.end() ){
								col1.push_back(pt.at(i).getLineNum());
								col2.push_back(varTable.getVarIndex(pt.at(i).getVarName()));
							}
						}
					}
				}
			}
			// While/If
			else{
				for(int i=0;i<pt.size();i++)
					if(patternType.at(pt.at(i).getType()) == q.ElementType){
						if( find(tcol1.begin(), tcol1.end(), pt.at(i).getLineNum()) != tcol1.end() &&
							find(tcol2.begin(), tcol2.end(), varTable.getVarIndex(pt.at(i).getVarName())) != tcol2.end() ){
							col1.push_back(pt.at(i).getLineNum());
							col2.push_back(varTable.getVarIndex(pt.at(i).getVarName()));
						}
					}
			}
			break;
			   }
		}
		queryTree.at(index).table.push_back(col1);
		queryTree.at(index).table.push_back(col2);
	}
}

void QueryProcessor::QueryCompare(compareQuery_t q, int index){
	AST ast = (*pkb).getAST();
	StmtTable st = (*pkb).getStmtTable();
	ConstTable constTable = (*pkb).getConstTable();
	ProcTable procTable = (*pkb).getProcTable();
	VarTable varTable = (*pkb).getVarTable();
	vector<int> callProc = (*pkb).getCalleeList();
	int totalLineNum = (*pkb).getTotalLineNum();

	// int compare
	//// assign
	if(q.leftType == "Assign"){
		if(q.rightType == "Assign" || q.rightType == "Statement"){
			vector<int> col1, col2;
			for(int i=1;i<=totalLineNum;i++){
				if(st.getLineDetails(i).type == "Assign"){
					col1.push_back(i);
					col2.push_back(i);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Stmtlst"){
			StmtLstTable stl = (*pkb).getStmtLstTable();
			vector<int> col1, col2;
			for(int i=0;i<stl.getSize();i++){
				int line = stl.getStartLine(i);
				if(st.getLineDetails(line).type == "Assign"){
					col1.push_back(line);
					col2.push_back(line);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Constant"){
			vector<int> col1, col2;
			for(int i=0;i<constTable.getSize();i++){
				int n = constTable.getConstant(i);
				if(n<=totalLineNum && st.getLineDetails(n).type == "Assign"){
					col1.push_back(n);
					col2.push_back(n);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Integer"){
			vector<int> col1;
			int n = atoi(q.rightName.c_str());
			if(n<=totalLineNum && st.getLineDetails(n).type == "Assign"){
				col1.push_back(n);
			}
			queryTree.at(index).table.push_back(col1);
		}
	}
	//////////////////////////////////////
	//// while
	else if(q.leftType == "While"){
		if(q.rightType == "While" || q.rightType == "Statement"){
			vector<int> col1, col2;		
			for(int i=1;i<=totalLineNum;i++){
				if(st.getLineDetails(i).type == "While"){
					col1.push_back(i);
					col2.push_back(i);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Stmtlst"){
			StmtLstTable stl = (*pkb).getStmtLstTable();
			vector<int> col1, col2;
			for(int i=0;i<stl.getSize();i++){
				int line = stl.getStartLine(i);
				if(st.getLineDetails(line).type == "While"){
					col1.push_back(line);
					col2.push_back(line);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Constant"){
			vector<int> col1, col2;
			
			for(int i=0;i<constTable.getSize();i++){
				int n = constTable.getConstant(i);
				if(n<=totalLineNum && st.getLineDetails(n).type == "While"){
					col1.push_back(n);
					col2.push_back(n);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Integer"){
			vector<int> col1;
			
			int n = atoi(q.rightName.c_str());
			if(n<=totalLineNum && st.getLineDetails(n).type == "While"){
				col1.push_back(n);
			}
			queryTree.at(index).table.push_back(col1);
		}
	}
	//////////////////////////////////////
	//// if
	else if(q.leftType == "If"){
		if(q.rightType == "If" || q.rightType == "Statement"){
			vector<int> col1, col2;
			
			for(int i=1;i<=totalLineNum;i++){
				if(st.getLineDetails(i).type == "If"){
					col1.push_back(i);
					col2.push_back(i);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Stmtlst"){
			StmtLstTable stl = (*pkb).getStmtLstTable();
			vector<int> col1, col2;
			for(int i=0;i<stl.getSize();i++){
				int line = stl.getStartLine(i);
				if(st.getLineDetails(line).type == "If"){
					col1.push_back(line);
					col2.push_back(line);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Constant"){
			vector<int> col1, col2;
			
			for(int i=0;i<constTable.getSize();i++){
				int n = constTable.getConstant(i);
				if(n<=totalLineNum && st.getLineDetails(n).type == "If"){
					col1.push_back(n);
					col2.push_back(n);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Integer"){
			vector<int> col1;
			
			int n = atoi(q.rightName.c_str());
			if(n<=totalLineNum && st.getLineDetails(n).type == "If"){
				col1.push_back(n);
			}
			queryTree.at(index).table.push_back(col1);
		}
	}
	///////////////////////
	//// Call
	else if(q.leftType == "Call"){
		if(q.rightType == "Call" || q.rightType == "Statement"){
			vector<int> col1, col2;
			
			for(int i=1;i<=totalLineNum;i++){
				if(st.getLineDetails(i).type == "Call"){
					col1.push_back(i);
					col2.push_back(i);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Stmtlst"){
			StmtLstTable stl = (*pkb).getStmtLstTable();
			vector<int> col1, col2;
			for(int i=0;i<stl.getSize();i++){
				int line = stl.getStartLine(i);
				if(st.getLineDetails(line).type == "Call"){
					col1.push_back(line);
					col2.push_back(line);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Constant"){
			vector<int> col1, col2;
			
			for(int i=0;i<constTable.getSize();i++){
				int n = constTable.getConstant(i);
				if(n<=totalLineNum && st.getLineDetails(n).type == "Call"){
					col1.push_back(n);
					col2.push_back(n);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Integer"){
			vector<int> col1;
			
			int n = atoi(q.rightName.c_str());
			if(n<=totalLineNum && st.getLineDetails(n).type == "Call"){
				col1.push_back(n);
			}
			queryTree.at(index).table.push_back(col1);
		}
	}
	//////////////////////////////////////
	//// stmt
	else if(q.leftType == "Statement"){
		if(q.rightType == "Assign"){
			vector<int> col1, col2;
			
			for(int i=1;i<=totalLineNum;i++){
				if(st.getLineDetails(i).type == "Assign"){
					col1.push_back(i);
					col2.push_back(i);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "While"){
			vector<int> col1, col2;
			
			for(int i=1;i<=totalLineNum;i++){
				if(st.getLineDetails(i).type == "While"){
					col1.push_back(i);
					col2.push_back(i);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "If"){
			vector<int> col1, col2;
			
			for(int i=1;i<=totalLineNum;i++){
				if(st.getLineDetails(i).type == "If"){
					col1.push_back(i);
					col2.push_back(i);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Call"){
			vector<int> col1, col2;

			for(int i=1;i<=totalLineNum;i++){
				if(st.getLineDetails(i).type == "Call"){
					col1.push_back(i);
					col2.push_back(i);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Statement"){
			vector<int> col1, col2;
			
			for(int i=1;i<=totalLineNum;i++){
				col1.push_back(i);
				col2.push_back(i);
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Stmtlst"){
			StmtLstTable stl = (*pkb).getStmtLstTable();
			vector<int> col1, col2;
			for(int i=0;i<stl.getSize();i++){
				int line = stl.getStartLine(i);
				col1.push_back(line);
				col2.push_back(line);
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Constant"){
			vector<int> col1, col2;
			
			for(int i=0;i<constTable.getSize();i++){
				int n = constTable.getConstant(i);
				if(n<=totalLineNum){
					col1.push_back(n);
					col2.push_back(n);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Integer"){
			vector<int> col1;
			
			int n = atoi(q.rightName.c_str());
			if(n<=totalLineNum)
				col1.push_back(n);

			queryTree.at(index).table.push_back(col1);
		}
	}
	//////////////////////////////////////
	//// StmtLst
	else if(q.leftName == "Stmtlst"){
		if(q.rightType == "Assign"){
			StmtLstTable stl = (*pkb).getStmtLstTable();
			vector<int> col1, col2;
			for(int i=0;i<stl.getSize();i++){
				int line = stl.getStartLine(i);
				if(st.getLineDetails(line).type == "Assign"){
					col1.push_back(line);
					col2.push_back(line);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "While"){
			StmtLstTable stl = (*pkb).getStmtLstTable();
			vector<int> col1, col2;
			for(int i=0;i<stl.getSize();i++){
				int line = stl.getStartLine(i);
				if(st.getLineDetails(line).type == "While"){
					col1.push_back(line);
					col2.push_back(line);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "If"){
			StmtLstTable stl = (*pkb).getStmtLstTable();
			vector<int> col1, col2;
			for(int i=0;i<stl.getSize();i++){
				int line = stl.getStartLine(i);
				if(st.getLineDetails(line).type == "If"){
					col1.push_back(line);
					col2.push_back(line);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Call"){
			StmtLstTable stl = (*pkb).getStmtLstTable();
			vector<int> col1, col2;
			for(int i=0;i<stl.getSize();i++){
				int line = stl.getStartLine(i);
				if(st.getLineDetails(line).type == "Call"){
					col1.push_back(line);
					col2.push_back(line);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Statement" || q.rightName == "StmtLst"){
			StmtLstTable stl = (*pkb).getStmtLstTable();
			vector<int> col1, col2;
			for(int i=0;i<stl.getSize();i++){
				int line = stl.getStartLine(i);
				col1.push_back(line);
				col2.push_back(line);
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Constant"){
			StmtLstTable stl = (*pkb).getStmtLstTable();
			vector<int> col1, col2;
			for(int i=0;i<stl.getSize();i++){
				int line = stl.getStartLine(i);
				if(constTable.hasCon(line)){
					col1.push_back(line);
					col2.push_back(line);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Integer"){
			StmtLstTable stl = (*pkb).getStmtLstTable();
			vector<int> col1, col2;
			for(int i=0;i<stl.getSize();i++){
				int line = stl.getStartLine(i), c = atoi(q.rightName.c_str());
				if(line == c){
					col1.push_back(line);
					col2.push_back(line);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
	}
	//////////////////////////////////////
	//// const
	else if(q.leftType == "Constant"){
		if(q.rightType == "Assign"){
			vector<int> col1, col2;
			
			for(int i=0;i<constTable.getSize();i++){
				int n = constTable.getConstant(i);
				if(n<=totalLineNum && st.getLineDetails(n).type == "Assign"){
					col1.push_back(n);
					col2.push_back(n);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "While"){
			vector<int> col1, col2;
			
			for(int i=0;i<constTable.getSize();i++){
				int n = constTable.getConstant(i);
				if(n<=totalLineNum && st.getLineDetails(n).type == "While"){
					col1.push_back(n);
					col2.push_back(n);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "If"){
			vector<int> col1, col2;
			
			for(int i=0;i<constTable.getSize();i++){
				int n = constTable.getConstant(i);
				if(n<=totalLineNum && st.getLineDetails(n).type == "If"){
					col1.push_back(n);
					col2.push_back(n);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Call"){
			vector<int> col1, col2;
			
			for(int i=0;i<constTable.getSize();i++){
				int n = constTable.getConstant(i);
				if(n<=totalLineNum && st.getLineDetails(n).type == "Call"){
					col1.push_back(n);
					col2.push_back(n);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Statement"){
			vector<int> col1, col2;
			
			for(int i=0;i<constTable.getSize();i++){
				int n = constTable.getConstant(i);
				if(n<=totalLineNum){
					col1.push_back(n);
					col2.push_back(n);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Stmtlst"){
			StmtLstTable stl = (*pkb).getStmtLstTable();
			vector<int> col1, col2;
			for(int i=0;i<stl.getSize();i++){
				int line = stl.getStartLine(i);
				if(constTable.hasCon(line)){
					col1.push_back(line);
					col2.push_back(line);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Constant"){
			vector<int> col1, col2;
			
			for(int i=0;i<constTable.getSize();i++){
				int n = constTable.getConstant(i);
				col1.push_back(n);
				col2.push_back(n);
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Integer"){
			vector<int> col1;
			
			int n = atoi(q.rightName.c_str());
			if(constTable.hasCon(n))
				col1.push_back(n);

			queryTree.at(index).table.push_back(col1);
		}
	}
	//////////////////////////////////////
	//// int
	else if(q.leftType == "Integer"){
		int n = atoi(q.leftName.c_str());
		if(q.rightType == "Assign"){
			vector<int> col1;
			
			if(st.getLineDetails(n).type == "Assign")
				col1.push_back(n);

			queryTree.at(index).table.push_back(col1);
		}
		else if(q.rightType == "While"){
			vector<int> col1;
			
			if(st.getLineDetails(n).type == "While")
				col1.push_back(n);

			queryTree.at(index).table.push_back(col1);
		}
		else if(q.rightType == "If"){
			vector<int> col1;
			
			if(st.getLineDetails(n).type == "If")
				col1.push_back(n);

			queryTree.at(index).table.push_back(col1);
		}
		else if(q.rightType == "Call"){
			vector<int> col1;
			
			if(st.getLineDetails(n).type == "Call")
				col1.push_back(n);

			queryTree.at(index).table.push_back(col1);
		}
		else if(q.rightType == "Statement"){
			vector<int> col1;
			col1.push_back(n);
			queryTree.at(index).table.push_back(col1);
		}
		else if(q.rightType == "Stmtlst"){
			StmtLstTable stl = (*pkb).getStmtLstTable();
			vector<int> col1, col2;
			for(int i=0;i<stl.getSize();i++){
				int line = stl.getStartLine(i), c = atoi(q.rightName.c_str());
				if(line == c){
					col1.push_back(line);
					col2.push_back(line);
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Constant"){
			vector<int> col1;
			if(constTable.hasCon(n))
				col1.push_back(n);
			queryTree.at(index).table.push_back(col1);
		}
		else if(q.rightType == "Integer"){
		}
	}

	// string compare
	/////////////////
	//// Proc
	else if(q.leftType == "Procedure"){
		if(q.rightType == "Procedure"){
			vector<int> col1, col2;
			
			for(int i=0;i<procTable.getSize();i++){
				col1.push_back(i);
				col2.push_back(i);
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "CallProc"){
			vector<int> col1, col2;
			
			for(int i=0;i<callProc.size();i++){
				col1.push_back(callProc.at(i));
				col2.push_back(callProc.at(i));
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Variable"){
			vector<int> col1, col2;
			
			for(int i=0;i<procTable.getSize();i++){
				for(int j=0;j<varTable.getSize();j++){
					if(procTable.getProName(i) == varTable.getVarName(j)){
						col1.push_back(i);
						col2.push_back(j);
					}
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "String"){
			vector<int> col1;
			
			for(int i=0;i<procTable.getSize();i++){
				if(procTable.getProName(i) == q.rightName){
					col1.push_back(i);
				}
			}
			queryTree.at(index).table.push_back(col1);
		}
	}
	///////////////
	//// callproc
	else if(q.leftType == "CallProc"){
		if(q.rightType == "CallProc"){
			vector<int> col1, col2;

			for(int i=0;i<callProc.size();i++){
				col1.push_back(callProc.at(i));
				col2.push_back(callProc.at(i));
			}

			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Variable"){
			vector<int> col1, col2;
			
			for(int i=0;i<callProc.size();i++){
				for(int j=0;j<varTable.getSize();j++){
					if(procTable.getProName(callProc.at(i)) == varTable.getVarName(j)){
						col1.push_back(callProc.at(i));
						col2.push_back(j);
					}
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "String"){
			vector<int> col1;
			
			for(int i=0;i<callProc.size();i++){
				if(procTable.getProName(callProc.at(i)) == q.rightName){
					col1.push_back(callProc.at(i));
				}
			}

			queryTree.at(index).table.push_back(col1);
		}
	}
	//////////////
	//// variable
	else if(q.leftType == "Variable"){
		if(q.rightType == "Procedure"){
			vector<int> col1, col2;
			
			for(int i=0;i<procTable.getSize();i++){
				for(int j=0;j<varTable.getSize();j++){
					if(procTable.getProName(i) == varTable.getVarName(j)){
						col1.push_back(i);
						col2.push_back(j);
					}
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "CallProc"){
			vector<int> col1, col2;
			
			for(int i=0;i<callProc.size();i++){
				for(int j=0;j<varTable.getSize();j++){
					if(procTable.getProName(callProc.at(i)) == varTable.getVarName(j)){
						col1.push_back(callProc.at(i));
						col2.push_back(j);
					}
				}
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "Variable"){
			vector<int> col1, col2;

			for(int i=0;i<varTable.getSize();i++){
				col1.push_back(i);
				col2.push_back(i);
			}
			queryTree.at(index).table.push_back(col1);
			queryTree.at(index).table.push_back(col2);
		}
		else if(q.rightType == "String"){
			vector<int> col1;
			
			for(int i=0;i<varTable.getSize();i++){
				if(varTable.getVarName(i) == q.rightName){
					col1.push_back(i);
				}
			}
			queryTree.at(index).table.push_back(col1);
		}
	}
	///////////////
	//// string
	else if(q.leftType == "String"){
		if(q.rightType == "Procedure"){
			vector<int> col1;
			
			for(int i=0;i<procTable.getSize();i++){
				if(procTable.getProName(i) == q.leftName){
					col1.push_back(i);
				}
			}

			queryTree.at(index).table.push_back(col1);
		}
		else if(q.rightType == "CallProc"){
			vector<int> col1;
			
			for(int i=0;i<callProc.size();i++){
				if(procTable.getProName(callProc.at(i)) == q.leftName){
					col1.push_back(callProc.at(i));
				}
			}

			queryTree.at(index).table.push_back(col1);
		}
		else if(q.rightType == "Variable"){
			vector<int> col1;
			
			for(int i=0;i<varTable.getSize();i++){
				if(varTable.getVarName(i) == q.leftName){
					col1.push_back(i);
				}
			}
			queryTree.at(index).table.push_back(col1);
		}
		else if(q.rightType == "String"){
		}
	}
}

void QueryProcessor::BuildCallRelationTable(string c, int index){
	vector<int> col1,col2;

	Calls calls = (*pkb).getCalls();
	vector<Triple> callTable = calls.getCalls();
	for(int i=0;i<callTable.size();i++){
		col1.push_back(callTable.at(i).getFirst());
		col2.push_back(callTable.at(i).getThird());
	}

	queryTree.at(index).table.push_back(col1);
	queryTree.at(index).table.push_back(col2);
}


bool isConstant(string str){
	
	stringstream convert(str);
	int result;
	if(convert>>result)
	{
		return true;
	}
    return false;
}

bool isOperation(string str) {
	if ((str.compare("+")==0) || (str.compare("-")==0) || (str.compare("*")==0)) {
		return true;
	}
	return false;
}

bool isStatement(string str) {
	if ((str.compare("Assign")==0) || (str.compare("While")==0) || 
		(str.compare("If")==0) || (str.compare("Call")==0)) {
		return true;
	}
	return false;
}


void QueryProcessor::QueryContains(funcQuery_t q, int index) {
	Contains contains = (*pkb).getContains();
	ProcTable procTable = (*pkb).getProcTable();
	ConstTable consTable = (*pkb).getConstTable();
	VarTable varTable = (*pkb).getVarTable();
	StmtLstTable stmtLstTable = (*pkb).getStmtLstTable();
	PlusTable plusTable = (*pkb).getPlusTable();
	MinusTable minusTable = (*pkb).getMinusTable();
	TimesTable timesTable = (*pkb).getTimesTable();
	vector<int> col1, col2;

	vector<TNode> output; // record all the possible TNode for second arg
	//compute all the possible TNode for second arg first
	if (q.SecondElementType=="String"){
		if (isConstant(q.SecondElementName)) {
			int c2 = atoi(q.SecondElementName.c_str());
			int index = consTable.getConIndex(c2);
			output = contains.searchByIndex("Constant", index);
		} else if (isOperation(q.SecondElementName)) {
			output = contains.searchByType(q.SecondElementName);
		} else if (procTable.getProIndex(q.SecondElementName)!=-1) {
			int index = procTable.getProIndex(q.SecondElementName);
			output = contains.searchByIndex("Procedure", index);
		} else if (varTable.getVarIndex(q.SecondElementName)!=-1) {
			int index = varTable.getVarIndex(q.SecondElementName);
			output = contains.searchByIndex("Variable", index);
		}
	} else if (q.SecondElementType == "Integer") {
		int c2 = atoi(q.SecondElementName.c_str());
		output = contains.searchByProcline(c2);
	} else if (q.SecondElementType == "StmtLst") {
		output = contains.searchByType("StmtLst");
	} else if (q.SecondElementName == "_") {
		output = contains.getList();
	} else if (q.SecondElementType == "Statement") {
		vector<TNode> list = contains.getList();
		for (int i=0; i<list.size(); i++) {
			TNode temp = list.at(i);
			if (isStatement(temp.getNodeType())) {
				output.push_back(temp);
			}
		}
	} else if (q.SecondElementType == "Procedure") {
		output = contains.searchByType("Procedure");
	} else if (q.SecondElementType == "Variable") {
		output = contains.searchByType("Variable");
	} else if (q.SecondElementType == "Constant") {
		output = contains.searchByType("Constant");
	} else if (isStatement(q.SecondElementType)) {
		output = contains.searchByType(q.SecondElementType);
	} else if (isOperation(q.SecondElementType)) {
		output = contains.searchByType(q.SecondElementType);
	}

	//compute the result based on the output of second arg
	if (q.FirstElementType == "String") {
		if (isOperation(q.FirstElementName)) {
			for (int i=0; i<output.size(); i++) {
				TNode child = output.at(i);
				int ci = contains.getIndex(child);
				vector<TNode> parentV = contains.getParent(ci);
				for (int j=0; j<parentV.size(); j++) {
					TNode parent = parentV.at(j);
					if (parent.getNodeType()==q.FirstElementName) {
						col1.push_back(parent.getIndex());
						if ((q.SecondElementType=="Statement") || (isStatement(q.SecondElementType))) {
							col2.push_back(child.getProcLine());
						} else if (q.SecondElementType == "Constant") {
							int v = consTable.getConstant(child.getIndex());
							col2.push_back(v);
						} else if (q.SecondElementType == "StmtLst") {
							int pl = stmtLstTable.getStartLine(child.getIndex());
							col2.push_back(pl);
						} else if (q.SecondElementType == "+") {
							int pl = plusTable.getPlus(child.getIndex());
							col2.push_back(pl);
						} else if (q.SecondElementType == "-") {
							int pl = minusTable.getMinus(child.getIndex());
							col2.push_back(pl);
						} else if (q.SecondElementType == "*") {
							int pl = timesTable.getTimes(child.getIndex());
							col2.push_back(pl);
						} else {
							col2.push_back(child.getIndex());
						}
					}
				}
			}
		} else if (isConstant(q.FirstElementName)) {
			// Constant cannot be the parent
		} else if (procTable.getProIndex(q.FirstElementName)!=-1) {
			int index = procTable.getProIndex(q.FirstElementName);
			for (int i=0; i<output.size(); i++) {
				TNode child = output.at(i);
				int ci = contains.getIndex(child);
				vector<TNode> parentV = contains.getParent(ci);
				for (int j=0; j<parentV.size(); j++) {
					TNode parent = parentV.at(j);
					if ((parent.getNodeType()=="Procedure") && (parent.getIndex()==index)) {
						col1.push_back(index);
						if ((q.SecondElementType=="Statement") || (isStatement(q.SecondElementType))) {
							col2.push_back(child.getProcLine());
						} else if (q.SecondElementType == "Constant") {
							int v = consTable.getConstant(child.getIndex());
							col2.push_back(v);
						} else if (q.SecondElementType == "StmtLst") {
							int pl = stmtLstTable.getStartLine(child.getIndex());
							col2.push_back(pl);
						} else if (q.SecondElementType == "+") {
							int pl = plusTable.getPlus(child.getIndex());
							col2.push_back(pl);
						} else if (q.SecondElementType == "-") {
							int pl = minusTable.getMinus(child.getIndex());
							col2.push_back(pl);
						} else if (q.SecondElementType == "*") {
							int pl = timesTable.getTimes(child.getIndex());
							col2.push_back(pl);
						} else {
							col2.push_back(child.getIndex());
						}
					}
				}
			}
		} else if (varTable.getVarIndex(q.FirstElementName)!=-1) {
			// variable cannot be the parent
		}
	} else if (q.FirstElementType == "Integer") {
		int c1 = atoi(q.FirstElementName.c_str());
		for (int i=0; i<output.size(); i++) {
			TNode child = output.at(i);
			int ci = contains.getIndex(child);
			vector<TNode> parentV = contains.getParent(ci);
			for (int j=0; j<parentV.size(); j++) {
				TNode parent = parentV.at(j);
				if (parent.getProcLine()==c1) {
					col1.push_back(c1);
					if ((q.SecondElementType=="Statement") || (isStatement(q.SecondElementType))) {
						col2.push_back(child.getProcLine());
					} else if (q.SecondElementType == "Constant") {
						int v = consTable.getConstant(child.getIndex());
						col2.push_back(v);
					} else if (q.SecondElementType == "StmtLst") {
						int pl = stmtLstTable.getStartLine(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "+") {
						int pl = plusTable.getPlus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "-") {
						int pl = minusTable.getMinus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "*") {
						int pl = timesTable.getTimes(child.getIndex());
						col2.push_back(pl);
					} else {
						col2.push_back(child.getIndex());
					}
				}
			}
		}
	} else if (q.FirstElementType == "StmtLst") {
		for (int i=0; i<output.size(); i++) {
			TNode child = output.at(i);
			int ci = contains.getIndex(child);
			vector<TNode> parentV = contains.getParent(ci);
			for (int j=0; j<parentV.size(); j++) {
				TNode parent = parentV.at(j);
				if (parent.getNodeType()=="StmtLst") {
					int p = stmtLstTable.getStartLine(parent.getIndex());
					col1.push_back(p);
					if ((q.SecondElementType=="Statement") || (isStatement(q.SecondElementType))) {
						col2.push_back(child.getProcLine());
					} else if (q.SecondElementType == "Constant") {
						int v = consTable.getConstant(child.getIndex());
						col2.push_back(v);
					} else if (q.SecondElementType == "StmtLst") {
						int pl = stmtLstTable.getStartLine(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "+") {
						int pl = plusTable.getPlus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "-") {
						int pl = minusTable.getMinus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "*") {
						int pl = timesTable.getTimes(child.getIndex());
						col2.push_back(pl);
					} else {
						col2.push_back(child.getIndex());
					}
				}
			}
		}
	} else if (q.FirstElementName == "_") {
		for (int i=0; i<output.size(); i++) {
			TNode child = output.at(i);
			int ci = contains.getIndex(child);
			vector<TNode> parentV = contains.getParent(ci);
			for (int j=0; j<parentV.size(); j++) {
				TNode parent = parentV.at(j);
				col1.push_back(parent.getIndex());
				if ((q.SecondElementType=="Statement") || (isStatement(q.SecondElementType))) {
					col2.push_back(child.getProcLine());
				} else if (q.SecondElementType == "Constant") {
					int v = consTable.getConstant(child.getIndex());
					col2.push_back(v);
				} else if (q.SecondElementType == "StmtLst") {
					int pl = stmtLstTable.getStartLine(child.getIndex());
					col2.push_back(pl);
				} else if (q.SecondElementType == "+") {
					int pl = plusTable.getPlus(child.getIndex());
					col2.push_back(pl);
				} else if (q.SecondElementType == "-") {
					int pl = minusTable.getMinus(child.getIndex());
					col2.push_back(pl);
				} else if (q.SecondElementType == "*") {
					int pl = timesTable.getTimes(child.getIndex());
					col2.push_back(pl);
				} else {
					col2.push_back(child.getIndex());
				}
			}
		}
	} else if (q.FirstElementType == "Statement") {
		for (int i=0; i<output.size(); i++) {
			TNode child = output.at(i);
			int ci = contains.getIndex(child);
			vector<TNode> parentV = contains.getParent(ci);
			for (int j=0; j<parentV.size(); j++) {
				TNode parent = parentV.at(j);
				if (isStatement(parent.getNodeType())) {
					col1.push_back(parent.getProcLine());
					if ((q.SecondElementType=="Statement") || (isStatement(q.SecondElementType))) {
						col2.push_back(child.getProcLine());
					} else if (q.SecondElementType == "Constant") {
						int v = consTable.getConstant(child.getIndex());
						col2.push_back(v);
					} else if (q.SecondElementType == "StmtLst") {
						int pl = stmtLstTable.getStartLine(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "+") {
						int pl = plusTable.getPlus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "-") {
						int pl = minusTable.getMinus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "*") {
						int pl = timesTable.getTimes(child.getIndex());
						col2.push_back(pl);
					} else {
						col2.push_back(child.getIndex());
					}
				}
			}
		}
	} else if (q.FirstElementType == "Procedure") {
		for (int i=0; i<output.size(); i++) {
			TNode child = output.at(i);
			int ci = contains.getIndex(child);
			vector<TNode> parentV = contains.getParent(ci);
			for (int j=0; j<parentV.size(); j++) {
				TNode parent = parentV.at(j);
				if (parent.getNodeType()=="Procedure") {
					col1.push_back(parent.getIndex());
					if ((q.SecondElementType=="Statement") || (isStatement(q.SecondElementType))) {
						col2.push_back(child.getProcLine());
					} else if (q.SecondElementType == "Constant") {
						int v = consTable.getConstant(child.getIndex());
						col2.push_back(v);
					} else if (q.SecondElementType == "StmtLst") {
						int pl = stmtLstTable.getStartLine(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "+") {
						int pl = plusTable.getPlus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "-") {
						int pl = minusTable.getMinus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "*") {
						int pl = timesTable.getTimes(child.getIndex());
						col2.push_back(pl);
					} else {
						col2.push_back(child.getIndex());
					}
				}
			}
		}
	} else if (q.FirstElementType == "Variable") {
		// variable cannot be parent
	} else if (q.FirstElementType == "Constant") {
		// constant cannot be parent
	} else if (isStatement(q.FirstElementType)) {
		for (int i=0; i<output.size(); i++) {
			TNode child = output.at(i);
			int ci = contains.getIndex(child);
			vector<TNode> parentV = contains.getParent(ci);
			for (int j=0; j<parentV.size(); j++) {
				TNode parent = parentV.at(j);
				if (parent.getNodeType()==q.FirstElementType) {
					col1.push_back(parent.getProcLine());
					if ((q.SecondElementType=="Statement") || (isStatement(q.SecondElementType))) {
						col2.push_back(child.getProcLine());
					} else if (q.SecondElementType == "Constant") {
						int v = consTable.getConstant(child.getIndex());
						col2.push_back(v);
					} else if (q.SecondElementType == "StmtLst") {
						int pl = stmtLstTable.getStartLine(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "+") {
						int pl = plusTable.getPlus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "-") {
						int pl = minusTable.getMinus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "*") {
						int pl = timesTable.getTimes(child.getIndex());
						col2.push_back(pl);
					} else {
						col2.push_back(child.getIndex());
					}
				}
			}
		}
	} else if (isOperation(q.FirstElementType)) {
		for (int i=0; i<output.size(); i++) {
			TNode child = output.at(i);
			int ci = contains.getIndex(child);
			vector<TNode> parentV = contains.getParent(ci);
			for (int j=0; j<parentV.size(); j++) {
				TNode parent = parentV.at(j);
				if (parent.getNodeType()==q.FirstElementType) {
					int p;
					if (q.FirstElementType=="+") {
						p = plusTable.getPlus(parent.getIndex());
					} else if (q.FirstElementType=="-") {
						p = minusTable.getMinus(parent.getIndex());
					} else if (q.FirstElementType=="*") {
						p = timesTable.getTimes(parent.getIndex());
					}
					col1.push_back(p);
					if ((q.SecondElementType=="Statement") || (isStatement(q.SecondElementType))) {
						col2.push_back(child.getProcLine());
					} else if (q.SecondElementType == "Constant") {
						int v = consTable.getConstant(child.getIndex());
						col2.push_back(v);
					} else if (q.SecondElementType == "StmtLst") {
						int pl = stmtLstTable.getStartLine(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "+") {
						int pl = plusTable.getPlus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "-") {
						int pl = minusTable.getMinus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "*") {
						int pl = timesTable.getTimes(child.getIndex());
						col2.push_back(pl);
					} else {
						col2.push_back(child.getIndex());
					}
				}
			}
		}
	}

	queryTree.at(index).table.push_back(col1);
	queryTree.at(index).table.push_back(col2);
}

void QueryProcessor::QueryContainsStar(funcQuery_t q, int index) {
	Contains contains = (*pkb).getContains();
	ProcTable procTable = (*pkb).getProcTable();
	ConstTable consTable = (*pkb).getConstTable();
	VarTable varTable = (*pkb).getVarTable();
	StmtLstTable stmtLstTable = (*pkb).getStmtLstTable();
	PlusTable plusTable = (*pkb).getPlusTable();
	MinusTable minusTable = (*pkb).getMinusTable();
	TimesTable timesTable = (*pkb).getTimesTable();
	vector<int> col1, col2;

	vector<TNode> output; // record all the possible TNode for second arg
	//compute all the possible TNode for second arg first
	if (q.SecondElementType=="String"){
		if (isConstant(q.SecondElementName)) {
			int c2 = atoi(q.SecondElementName.c_str());
			int index = consTable.getConIndex(c2);
			output = contains.searchByIndex("Constant", index);
		} else if (isOperation(q.SecondElementName)) {
			output = contains.searchByType(q.SecondElementName);
		} else if (procTable.getProIndex(q.SecondElementName)!=-1) {
			int index = procTable.getProIndex(q.SecondElementName);
			output = contains.searchByIndex("Procedure", index);
		} else if (varTable.getVarIndex(q.SecondElementName)!=-1) {
			int index = varTable.getVarIndex(q.SecondElementName);
			output = contains.searchByIndex("Variable", index);
		}
	} else if (q.SecondElementType == "Integer") {
		int c2 = atoi(q.SecondElementName.c_str());
		output = contains.searchByProcline(c2);
	} else if (q.SecondElementType == "StmtLst") {
		output = contains.searchByType("StmtLst");
	} else if (q.SecondElementName == "_") {
		output = contains.getList();
	} else if (q.SecondElementType == "Statement") {
		vector<TNode> list = contains.getList();
		for (int i=0; i<list.size(); i++) {
			TNode temp = list.at(i);
			if (isStatement(temp.getNodeType())) {
				output.push_back(temp);
			}
		}
	} else if (q.SecondElementType == "Procedure") {
		output = contains.searchByType("Procedure");
	} else if (q.SecondElementType == "Variable") {
		output = contains.searchByType("Variable");
	} else if (q.SecondElementType == "Constant") {
		output = contains.searchByType("Constant");
	} else if (isStatement(q.SecondElementType)) {
		output = contains.searchByType(q.SecondElementType);
	} else if (isOperation(q.SecondElementType)) {
		output = contains.searchByType(q.SecondElementType);
	}

	//compute the result based on the output of second arg
	if (q.FirstElementType == "String") {
		if (isOperation(q.FirstElementName)) {
			for (int i=0; i<output.size(); i++) {
				TNode child = output.at(i);
				int ci = contains.getIndex(child);
				vector<TNode> parentV = contains.getParentStar(ci);
				for (int j=0; j<parentV.size(); j++) {
					TNode parent = parentV.at(j);
					if (parent.getNodeType()==q.FirstElementName) {
						col1.push_back(parent.getIndex());
						if ((q.SecondElementType=="Statement") || (isStatement(q.SecondElementType))) {
							col2.push_back(child.getProcLine());
						} else if (q.SecondElementType == "Constant") {
							int v = consTable.getConstant(child.getIndex());
							col2.push_back(v);
						} else if (q.SecondElementType == "StmtLst") {
							int pl = stmtLstTable.getStartLine(child.getIndex());
							col2.push_back(pl);
						} else if (q.SecondElementType == "+") {
							int pl = plusTable.getPlus(child.getIndex());
							col2.push_back(pl);
						} else if (q.SecondElementType == "-") {
							int pl = minusTable.getMinus(child.getIndex());
							col2.push_back(pl);
						} else if (q.SecondElementType == "*") {
							int pl = timesTable.getTimes(child.getIndex());
							col2.push_back(pl);
						} else {
							col2.push_back(child.getIndex());
						}
					}
				}
			}
		} else if (isConstant(q.FirstElementName)) {
			// Constant cannot be the parent
		} else if (procTable.getProIndex(q.FirstElementName)!=-1) {
			int index = procTable.getProIndex(q.FirstElementName);
			for (int i=0; i<output.size(); i++) {
				TNode child = output.at(i);
				int ci = contains.getIndex(child);
				vector<TNode> parentV = contains.getParentStar(ci);
				for (int j=0; j<parentV.size(); j++) {
					TNode parent = parentV.at(j);
					if ((parent.getNodeType()=="Procedure") && (parent.getIndex()==index)) {
						col1.push_back(index);
						if ((q.SecondElementType=="Statement") || (isStatement(q.SecondElementType))) {
							col2.push_back(child.getProcLine());
						} else if (q.SecondElementType == "Constant") {
							int v = consTable.getConstant(child.getIndex());
							col2.push_back(v);
						} else if (q.SecondElementType == "StmtLst") {
							int pl = stmtLstTable.getStartLine(child.getIndex());
							col2.push_back(pl);
						} else if (q.SecondElementType == "+") {
							int pl = plusTable.getPlus(child.getIndex());
							col2.push_back(pl);
						} else if (q.SecondElementType == "-") {
							int pl = minusTable.getMinus(child.getIndex());
							col2.push_back(pl);
						} else if (q.SecondElementType == "*") {
							int pl = timesTable.getTimes(child.getIndex());
							col2.push_back(pl);
						} else {
							col2.push_back(child.getIndex());
						}
					}
				}
			}
		} else if (varTable.getVarIndex(q.FirstElementName)!=-1) {
			// variable cannot be the parent
		}
	} else if (q.FirstElementType == "Integer") {
		int c1 = atoi(q.FirstElementName.c_str());
		for (int i=0; i<output.size(); i++) {
			TNode child = output.at(i);
			int ci = contains.getIndex(child);
			vector<TNode> parentV = contains.getParentStar(ci);
			for (int j=0; j<parentV.size(); j++) {
				TNode parent = parentV.at(j);
				if (parent.getProcLine()==c1) {
					col1.push_back(c1);
					if ((q.SecondElementType=="Statement") || (isStatement(q.SecondElementType))) {
						col2.push_back(child.getProcLine());
					} else if (q.SecondElementType == "Constant") {
						int v = consTable.getConstant(child.getIndex());
						col2.push_back(v);
					} else if (q.SecondElementType == "StmtLst") {
						int pl = stmtLstTable.getStartLine(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "+") {
						int pl = plusTable.getPlus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "-") {
						int pl = minusTable.getMinus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "*") {
						int pl = timesTable.getTimes(child.getIndex());
						col2.push_back(pl);
					} else {
						col2.push_back(child.getIndex());
					}
				}
			}
		}
	} else if (q.FirstElementType == "StmtLst") {
		for (int i=0; i<output.size(); i++) {
			TNode child = output.at(i);
			int ci = contains.getIndex(child);
			vector<TNode> parentV = contains.getParentStar(ci);
			for (int j=0; j<parentV.size(); j++) {
				TNode parent = parentV.at(j);
				if (parent.getNodeType()=="StmtLst") {
					int p = stmtLstTable.getStartLine(parent.getIndex());
					col1.push_back(p);
					if ((q.SecondElementType=="Statement") || (isStatement(q.SecondElementType))) {
						col2.push_back(child.getProcLine());
					} else if (q.SecondElementType == "Constant") {
						int v = consTable.getConstant(child.getIndex());
						col2.push_back(v);
					} else if (q.SecondElementType == "StmtLst") {
						int pl = stmtLstTable.getStartLine(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "+") {
						int pl = plusTable.getPlus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "-") {
						int pl = minusTable.getMinus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "*") {
						int pl = timesTable.getTimes(child.getIndex());
						col2.push_back(pl);
					} else {
						col2.push_back(child.getIndex());
					}
				}
			}
		}
	} else if (q.FirstElementName == "_") {
		for (int i=0; i<output.size(); i++) {
			TNode child = output.at(i);
			int ci = contains.getIndex(child);
			vector<TNode> parentV = contains.getParentStar(ci);
			for (int j=0; j<parentV.size(); j++) {
				TNode parent = parentV.at(j);
				col1.push_back(parent.getIndex());
				if ((q.SecondElementType=="Statement") || (isStatement(q.SecondElementType))) {
					col2.push_back(child.getProcLine());
				} else if (q.SecondElementType == "Constant") {
					int v = consTable.getConstant(child.getIndex());
					col2.push_back(v);
				} else if (q.SecondElementType == "StmtLst") {
					int pl = stmtLstTable.getStartLine(child.getIndex());
					col2.push_back(pl);
				} else if (q.SecondElementType == "+") {
					int pl = plusTable.getPlus(child.getIndex());
					col2.push_back(pl);
				} else if (q.SecondElementType == "-") {
					int pl = minusTable.getMinus(child.getIndex());
					col2.push_back(pl);
				} else if (q.SecondElementType == "*") {
					int pl = timesTable.getTimes(child.getIndex());
					col2.push_back(pl);
				} else {
					col2.push_back(child.getIndex());
				}
			}
		}
	} else if (q.FirstElementType == "Statement") {
		for (int i=0; i<output.size(); i++) {
			TNode child = output.at(i);
			int ci = contains.getIndex(child);
			vector<TNode> parentV = contains.getParentStar(ci);
			for (int j=0; j<parentV.size(); j++) {
				TNode parent = parentV.at(j);
				if (isStatement(parent.getNodeType())) {
					col1.push_back(parent.getProcLine());
					if ((q.SecondElementType=="Statement") || (isStatement(q.SecondElementType))) {
						col2.push_back(child.getProcLine());
					} else if (q.SecondElementType == "Constant") {
						int v = consTable.getConstant(child.getIndex());
						col2.push_back(v);
					} else if (q.SecondElementType == "StmtLst") {
						int pl = stmtLstTable.getStartLine(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "+") {
						int pl = plusTable.getPlus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "-") {
						int pl = minusTable.getMinus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "*") {
						int pl = timesTable.getTimes(child.getIndex());
						col2.push_back(pl);
					} else {
						col2.push_back(child.getIndex());
					}
				}
			}
		}
	} else if (q.FirstElementType == "Procedure") {
		for (int i=0; i<output.size(); i++) {
			TNode child = output.at(i);
			int ci = contains.getIndex(child);
			vector<TNode> parentV = contains.getParentStar(ci);
			for (int j=0; j<parentV.size(); j++) {
				TNode parent = parentV.at(j);
				if (parent.getNodeType()=="Procedure") {
					col1.push_back(parent.getIndex());
					if ((q.SecondElementType=="Statement") || (isStatement(q.SecondElementType))) {
						col2.push_back(child.getProcLine());
					} else if (q.SecondElementType == "Constant") {
						int v = consTable.getConstant(child.getIndex());
						col2.push_back(v);
					} else if (q.SecondElementType == "StmtLst") {
						int pl = stmtLstTable.getStartLine(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "+") {
						int pl = plusTable.getPlus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "-") {
						int pl = minusTable.getMinus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "*") {
						int pl = timesTable.getTimes(child.getIndex());
						col2.push_back(pl);
					} else {
						col2.push_back(child.getIndex());
					}
				}
			}
		}
	} else if (q.FirstElementType == "Variable") {
		// variable cannot be parent
	} else if (q.FirstElementType == "Constant") {
		// constant cannot be parent
	} else if (isStatement(q.FirstElementType)) {
		for (int i=0; i<output.size(); i++) {
			TNode child = output.at(i);
			int ci = contains.getIndex(child);
			vector<TNode> parentV = contains.getParentStar(ci);
			for (int j=0; j<parentV.size(); j++) {
				TNode parent = parentV.at(j);
				if (parent.getNodeType()==q.FirstElementType) {
					col1.push_back(parent.getProcLine());
					if ((q.SecondElementType=="Statement") || (isStatement(q.SecondElementType))) {
						col2.push_back(child.getProcLine());
					} else if (q.SecondElementType == "Constant") {
						int v = consTable.getConstant(child.getIndex());
						col2.push_back(v);
					} else if (q.SecondElementType == "StmtLst") {
						int pl = stmtLstTable.getStartLine(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "+") {
						int pl = plusTable.getPlus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "-") {
						int pl = minusTable.getMinus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "*") {
						int pl = timesTable.getTimes(child.getIndex());
						col2.push_back(pl);
					} else {
						col2.push_back(child.getIndex());
					}
				}
			}
		}
	} else if (isOperation(q.FirstElementType)) {
		for (int i=0; i<output.size(); i++) {
			TNode child = output.at(i);
			int ci = contains.getIndex(child);
			vector<TNode> parentV = contains.getParentStar(ci);
			for (int j=0; j<parentV.size(); j++) {
				TNode parent = parentV.at(j);
				if (parent.getNodeType()==q.FirstElementType) {
					int p;
					if (q.FirstElementType=="+") {
						p = plusTable.getPlus(parent.getIndex());
					} else if (q.FirstElementType=="-") {
						p = minusTable.getMinus(parent.getIndex());
					} else if (q.FirstElementType=="*") {
						p = timesTable.getTimes(parent.getIndex());
					}
					col1.push_back(p);
					if ((q.SecondElementType=="Statement") || (isStatement(q.SecondElementType))) {
						col2.push_back(child.getProcLine());
					} else if (q.SecondElementType == "Constant") {
						int v = consTable.getConstant(child.getIndex());
						col2.push_back(v);
					} else if (q.SecondElementType == "StmtLst") {
						int pl = stmtLstTable.getStartLine(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "+") {
						int pl = plusTable.getPlus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "-") {
						int pl = minusTable.getMinus(child.getIndex());
						col2.push_back(pl);
					} else if (q.SecondElementType == "*") {
						int pl = timesTable.getTimes(child.getIndex());
						col2.push_back(pl);
					} else {
						col2.push_back(child.getIndex());
					}
				}
			}
		}
	}

	
	queryTree.at(index).table.push_back(col1);
	queryTree.at(index).table.push_back(col2);
}


vector<string> QueryProcessor::findVarNames(vector<int> index){
	VarTable varTable = (*pkb).getVarTable();
	vector<string> varNames;
	int i;
	for(i=0;i<index.size();i++)
		varNames.push_back(varTable.getVarName(index.at(i)));
	return varNames;
}

bool QueryProcessor::hasVar(string v, vector<string> vList, int start, int end){
	int i;
	for(i=start;i<end;i++)
		if(v.compare(vList.at(i)) == 0)
			return true;
	return false;
}

bool QueryProcessor::isInList(int c, int v, vector<pair<int,int>> list){
	for(int i=0;i<list.size();i++)
		if(list.at(i).first == c && list.at(i).second == v)
			return true;
	return false;
}

list<string> QueryProcessor::convert(vector<int> v) {
	list<string> result;
	for (int i=0; i<v.size(); i++) {
		strstream ss;
		string s;
		ss << v[i];
		ss >> s;
		result.push_back(s);
	}
	return result;
}

list<string> QueryProcessor::convert(vector<string> v) {
	list<string> result;
	for (int i=0; i<v.size(); i++) {
		strstream ss;
		string s;
		ss << v[i];
		ss >> s;
		result.push_back(s);
	}
	return result;
}



// Query Evaluator functions
queryTreeNode_t QueryProcessor::mergeTable(queryTreeNode_t t1,queryTreeNode_t t2){
	vector<int> CommonIndexFort1,CommonIndexFort2;
	int NumOfCommonName=0;
	queryTreeNode_t result;
	if(t1.numOfColumn==2){
		if(t1.colName.at(0).compare(t1.colName.at(1))==0){
			t1.numOfColumn = 1;
			string singleValue = t1.colName.at(0); 
			t1.colName = vector<string>();
			t1.colName.push_back(singleValue);
			vector<int> singleTable = t1.table.at(0);
			t1.table = vector<vector<int>>();
			t1.table.push_back(singleTable);
		}
	}
	if(t2.numOfColumn==2){
		if(t2.colName.at(0).compare(t2.colName.at(1))==0){
			t2.numOfColumn = 1;
			string singleValue = t2.colName.at(0); 
			t2.colName = vector<string>();
			t2.colName.push_back(singleValue);
			vector<int> singleTable = t2.table.at(0);
			t2.table = vector<vector<int>>();
			t2.table.push_back(singleTable);
		}
	}
	//rearrange two table
	if((t2.numOfColumn>0)&&(!t2.table.empty())&&(!t2.table.at(0).empty())){
		for(int i=0;i<t1.numOfColumn;i++){
			for(int j=0;j<t2.numOfColumn;j++){
				if(t1.colName.at(i).compare (t2.colName.at(j))==0){
					string tempt1ColNamei=t1.colName.at(i);
					string tempt1ColNameC=t1.colName.at(NumOfCommonName);
					t1.colName.at(NumOfCommonName)=tempt1ColNamei;
					t1.colName.at(i)=tempt1ColNameC;

					vector<int> tempt1Tablei=t1.table.at(i);
					vector<int> tempt1TableC=t1.table.at(NumOfCommonName);
					t1.table.at(NumOfCommonName)=tempt1Tablei;
					t1.table.at(i)=tempt1TableC;

					string tempt2ColNamej=t2.colName.at(j);
					string tempt2ColNameC=t2.colName.at(NumOfCommonName);				
					t2.colName.at(NumOfCommonName)=tempt2ColNamej;				
					t2.colName.at(j)=tempt2ColNameC;

					vector<int> tempt2Tablej=t2.table.at(j);
					vector<int> tempt2TableC=t2.table.at(NumOfCommonName);
					t2.table.at(NumOfCommonName)=tempt2Tablej;
					t2.table.at(j)=tempt2TableC;

					NumOfCommonName++;
				}
			}
		}
	}
	vector<string> tempCommonCol;
	for(int su=0;su<NumOfCommonName;su++){
		tempCommonCol.push_back(t1.colName.at(su));
	}
	commonCol = tempCommonCol;

	if((t2.numOfColumn==0)||(t2.table.empty())||(t2.table.at(0).empty())||(t2.table.at(0).size()==0)){	
		result.numOfColumn=0;
		return result;
	}
	/*
	//check
	cout<<"t1"<<endl;
	for(int i=0;i<t1.numOfColumn;i++){
	cout<<t1.colName.at(i).c_str()<<" ";
	}
	cout<<endl;
	for(int i=0;i<t1.table.at(0).size();i++){
	for(int j=0;j<t1.numOfColumn;j++){
	cout<<t1.table.at(j).at(i)<<" ";
	}
	cout<<endl;
	}
	cout<<endl;
	cout<<"t2"<<endl;
	for(int i=0;i<t2.numOfColumn;i++){
	cout<<t2.colName.at(i).c_str()<<" ";
	}
	cout<<endl;
	for(int i=0;i<t2.table.at(0).size();i++){
	for(int j=0;j<t2.numOfColumn;j++){
	cout<<t2.table.at(j).at(i)<<" ";
	}
	cout<<endl;
	}
	cout<<endl;
	cout<<"check end"<<endl;
	*/
	result.numOfColumn=t1.numOfColumn+t2.numOfColumn-NumOfCommonName;

	//------------------------
	//choose common rows
	for(int i=0;i<t1.table.at(0).size();i++){
		for(int j=0;j<t2.table.at(0).size();j++){
			bool EqualFlag = true;
			for(int k=0;k<NumOfCommonName;k++){
				if(t1.table.at(k).at(i) != t2.table.at(k).at(j)){
					EqualFlag = false;
					break;
				}
			}
			if(EqualFlag==true){
				CommonIndexFort1.push_back(i);
				CommonIndexFort2.push_back(j);
			}
		}
	}
	//------------

	//merge
	//first deal with colName
	for(int i=0;i<NumOfCommonName;i++){
		result.colName.push_back(t1.colName.at(i));
	}
	for(int i=NumOfCommonName;i<t1.numOfColumn;i++){
		result.colName.push_back(t1.colName.at(i));
	}
	for(int i=NumOfCommonName;i<t2.numOfColumn;i++){
		result.colName.push_back(t2.colName.at(i));
	}

	//second deal with table
	for(int i=0;i<result.numOfColumn;i++){
		result.table.push_back(vector<int>());
	}

	for(int i=0;i<CommonIndexFort1.size();i++){
		for(int j=0;j<t1.numOfColumn;j++){
			result.table.at(j).push_back(t1.table.at(j).at(CommonIndexFort1.at(i)));
		}
		int j=t1.numOfColumn;
		for(int k=NumOfCommonName;k<t2.numOfColumn;k++){
			result.table.at(j).push_back(t2.table.at(k).at(CommonIndexFort2.at(i)));
			j++;
		}
	}

	return result;
}
vector<vector<int>> QueryProcessor::sortFirstAttr(vector<vector<int>> s){
	vector<vector<int>> v;
	vector<int> temp;
	for(int ih=0;ih<s.at(0).size();ih++){
		temp=vector<int>();
		for(int ii=0;ii<s.size();ii++){
			temp.push_back(s.at(ii).at(ih));
		}
		v.push_back(temp);
	}

	sort(v.begin(),v.end(),MySort(0));
	vector<vector<int>> result;
	for(int ik=0;ik<v.at(0).size();ik++){
		temp=vector<int>();
		for(int il=0;il<v.size();il++){
			temp.push_back(v.at(il).at(ik));
		}
		result.push_back(temp);
	}
	return result;
}


// Total processing
bool QueryProcessor::haveCommonFactor(queryTreeNode_t t1,queryTreeNode_t t2){
	bool flag = false;
	for(int i=0;i<t1.numOfColumn;i++){
		for(int j=0;j<t2.numOfColumn;j++){
			if(t1.colName.at(i).compare(t2.colName.at(j))==0){
				flag = true;
				break;
			}
		}
	}
	return flag;
}
void QueryProcessor::buildNodeIntoTree(int thisNode,vector<queryTreeNode_t> queryTree,
	vector<int>* inTree,vector<vector<int>>* orderTree,bool isInMajorTree,int majorCount,vector<vector<int>>* majorTreeList,int normalCount,vector<vector<int>>* normalTreeList){
	if(isInMajorTree){
		if(majorCount>=(*majorTreeList).size()){
			(*majorTreeList).push_back(vector<int>());
			(*majorTreeList).at(majorCount).push_back(thisNode);
		}else{
			(*majorTreeList).at(majorCount).push_back(thisNode);
		}
	}
	else{
		if(normalCount>=(*normalTreeList).size()){
			(*normalTreeList).push_back(vector<int>());
			(*normalTreeList).at(normalCount).push_back(thisNode);
		}else{
			(*normalTreeList).at(normalCount).push_back(thisNode);
		}
	}
	for(int i=0;i<queryTree.size();i++){
		if((*inTree).at(i)==0&&haveCommonFactor(queryTree.at(i),queryTree.at(thisNode))){
			(*inTree).at(i)=1;
			buildNodeIntoTree(i,queryTree,inTree,orderTree,isInMajorTree,majorCount,majorTreeList,normalCount,normalTreeList);
			(*orderTree).at(thisNode).push_back(i);
		}
	}
}
void QueryProcessor::orderOfMajorTree(int root,vector<vector<int>> orderTree,vector<int>* result){
	for(int i=0;i<orderTree.at(root).size();i++){
		(*result).push_back(orderTree.at(root).at(i));
		orderOfMajorTree(orderTree.at(root).at(i),orderTree,result);
	}
}

list<string> QueryProcessor::queryEvaluator(queryTreeNode_t t){
	VarTable varTable = (*pkb).getVarTable();
	ProcTable procTable = (*pkb).getProcTable();
	queryTreeNode_t finalTable = t;

	// Get results
	switch(selectType){
	case 1:{	
		vector<int> rBuffer;
		for(int i=0;i<finalTable.numOfColumn;i++){
			if(finalTable.colName.at(i).compare(selectedArgName) == 0){
				for(int j=0;j<finalTable.table.at(i).size();j++)
					rBuffer.push_back(finalTable.table.at(i).at(j));
				break;
			}
		}

		vector<int> result = rBuffer;
		return convert(result);
		break;
		   }
	case 2:{
		vector<int> rBuffer;
		for(int i=0;i<finalTable.numOfColumn;i++){
			if(finalTable.colName.at(i).compare(selectedArgName) == 0)
				for(int j=0;j<finalTable.table.at(i).size();j++)
					rBuffer.push_back(finalTable.table.at(i).at(j));
		}

		vector<string> result;
		for(int i=0;i<rBuffer.size();i++)
			result.push_back(varTable.getVarName(rBuffer.at(i)));
		return convert(result);
		break;
		   }
	case 3:{
		list<string> result;

		if(finalTable.numOfColumn == 0 || finalTable.table.empty() || finalTable.table.at(0).size() == 0)
			result.push_back("false");
		else result.push_back("true");
		return result;
		break;
		   }
	case 4:{
		vector<int> rBuffer;
		for(int i=0;i<finalTable.numOfColumn;i++){
			if(finalTable.colName.at(i).compare(selectedArgName) == 0)
				for(int j=0;j<finalTable.table.at(i).size();j++)
					rBuffer.push_back(finalTable.table.at(i).at(j));
		}

		vector<string> result;
		for(int i=0;i<rBuffer.size();i++)
			result.push_back(procTable.getProName(rBuffer.at(i)));
		return convert(result);
		break;
		   }
	case 5:{
		vector<vector<int>> rBuffer;
		vector<string> colType;
		list<string> result;
		for(int i=0;i<queries.selectQuery.tupleName.size();i++){
			for(int j=0;j<finalTable.numOfColumn;j++)
				if(finalTable.colName.at(j) == queries.selectQuery.tupleName.at(i)){
					colType.push_back(queries.selectQuery.tupleType.at(i));
					rBuffer.push_back(finalTable.table.at(j));
				}
		}
		if(rBuffer.size() > 0){
			for(int j=0;j<rBuffer.at(0).size();j++){
				stringstream r;
				for(int i=0;i<rBuffer.size();i++){
					if(	colType.at(i) == "Assign" || colType.at(i) == "While" || colType.at(i) == "If" || colType.at(i) == "Statement" || colType.at(i) == "Call" ||
						colType.at(i) == "StmtLst" || colType.at(i) == "+" || colType.at(i) == "-" || colType.at(i) == "*")
						r << rBuffer.at(i).at(j);
					else if(colType.at(i) == "Procedure" || colType.at(i) == "CallProc")
						r << procTable.getProName(rBuffer.at(i).at(j));
					else if(colType.at(i) == "Variable")
						r << varTable.getVarName(rBuffer.at(i).at(j));
					else if(colType.at(i) == "Constant")
						r << rBuffer.at(i).at(j);

					if(i != rBuffer.size()-1)
						r << " ";
				}
				result.push_back(r.str());
			}
		}
		return result;
		break;
		   }
	case 6:{
		vector<int> result;
		for(int i=0;i<finalTable.numOfColumn;i++){
			if(finalTable.colName.at(i).compare(selectedArgName) == 0)
				result = finalTable.table.at(i);
		}

		return convert(result);
		break;
		   }
	default:{
		break;
			}
	}
}



// Public functions
QueryProcessor::QueryProcessor(){
}

QueryProcessor::QueryProcessor(PKB* p){
	patternType.push_back("Assign");
	patternType.push_back("If");
	patternType.push_back("While");

	selectType = 0;

	pkb = p;
	affectsBip = AffectsBip(pkb);
}

list<string> QueryProcessor::processingQuery(string query){
	vector<string> vQuery = splitS(query, ';');
	string x_temp, y_temp;
	int size = vQuery.size();
	x_temp = "";
	for (int i =0; i<size-1; i++) {
		x_temp = x_temp + vQuery[i] + ";";
	}
	y_temp = trimL(vQuery[size-1]);
	// Reset the value.
	_query = pair<string,string>(x_temp, y_temp);

	bool isQueryValid = queryParser();
	if(isQueryValid == false) throw exception("Query is not valid.");
	queryTreeNode_t t=buildAndMergeTable();
	return queryEvaluator(t);
}

queryTreeNode_t QueryProcessor::firstRemove(queryTreeNode_t origin){
	queryTreeNode_t result;

	if(origin.numOfColumn==1){
		if((origin.colName.at(0).compare("_")==0||isdigit(origin.colName.at(0)[0]))&&(origin.type.compare("Select")!=0)){				 
			origin.numOfColumn=0;
			origin.colName = vector<string>();
			origin.table = vector<vector<int>>();
		}else{
		}

	}else{
		//col == 2
		if((origin.colName.at(0).compare("_")==0||isdigit(origin.colName.at(0)[0]))&&(origin.colName.at(1).compare("_")==0||isdigit(origin.colName.at(1)[0]))){
			origin.numOfColumn=0;
			origin.colName = vector<string>();
			origin.table = vector<vector<int>>();
		}else{
			if(origin.colName.at(0).compare("_")==0||isdigit(origin.colName.at(0)[0])){
				origin.numOfColumn=1;
				origin.colName.erase(origin.colName.begin());
				origin.table.erase(origin.table.begin());
				vector<int> temp;
				for(int ki=0;ki<origin.table.at(0).size();ki++){
					bool inSide = false;
					for(int kj=0;kj<temp.size();kj++){
						if(temp.at(kj)==origin.table.at(0).at(ki)){
							inSide =true;
							break;
						}
					}
					if(inSide==false){
						temp.push_back(origin.table.at(0).at(ki));
					}
				}
				origin.table.at(0) = temp;
			}else{
				if(origin.colName.at(1).compare("_")==0||isdigit(origin.colName.at(1)[0])){
					origin.numOfColumn=1;
					origin.colName.erase(origin.colName.begin()+1);
					origin.table.erase(origin.table.begin()+1);
					vector<int> temp;
					for(int ki=0;ki<origin.table.at(0).size();ki++){
						bool inSide = false;
						for(int kj=0;kj<temp.size();kj++){
							if(temp.at(kj)==origin.table.at(0).at(ki)){
								inSide =true;
								break;
							}
						}
						if(inSide==false){
							temp.push_back(origin.table.at(0).at(ki));
						}
					}
					origin.table.at(0) = temp;
				}else{
					if(origin.colName.at(0).compare(origin.colName.at(1))==0){
						origin.numOfColumn=1;
					    origin.colName.erase(origin.colName.begin()+1);
				   	    origin.table.erase(origin.table.begin()+1);
					}
				}
			}
		}
	}
	result = origin;
	return result;
}
